Commit b4c7f2e6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull integrity subsystem updates from Mimi Zohar:
 "An i_version change, one bug fix, and three kernel doc fixes:

   - instead of IMA detecting file change by directly accesssing
     i_version, it now calls vfs_getattr_nosec().

   - fix a race condition when inserting a new node in the iint rb-tree"

* tag 'integrity-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: Fix build warnings
  evm: Fix build warnings
  evm: Complete description of evm_inode_setattr()
  integrity: Fix possible multiple allocation in integrity_inode_get()
  IMA: use vfs_getattr_nosec to get the i_version
parents 21953eb1 95526d13
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ static const char evm_hmac[] = "hmac(sha1)";
/**
 * evm_set_key() - set EVM HMAC key from the kernel
 * @key: pointer to a buffer with the key data
 * @size: length of the key data
 * @keylen: length of the key data
 *
 * This function allows setting the EVM HMAC key from the kernel
 * without using the "encrypted" key subsystem keys. It can be used
+3 −1
Original line number Diff line number Diff line
@@ -318,7 +318,6 @@ int evm_protected_xattr_if_enabled(const char *req_xattr_name)
/**
 * evm_read_protected_xattrs - read EVM protected xattr names, lengths, values
 * @dentry: dentry of the read xattrs
 * @inode: inode of the read xattrs
 * @buffer: buffer xattr names, lengths or values are copied to
 * @buffer_size: size of buffer
 * @type: n: names, l: lengths, v: values
@@ -390,6 +389,7 @@ int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
 * @xattr_name: requested xattr
 * @xattr_value: requested xattr value
 * @xattr_value_len: requested xattr value length
 * @iint: inode integrity metadata
 *
 * Calculate the HMAC for the given dentry and verify it against the stored
 * security.evm xattr. For performance, use the xattr value and length
@@ -795,7 +795,9 @@ static int evm_attr_change(struct mnt_idmap *idmap,

/**
 * evm_inode_setattr - prevent updating an invalid EVM extended attribute
 * @idmap: idmap of the mount
 * @dentry: pointer to the affected dentry
 * @attr: iattr structure containing the new file attributes
 *
 * Permit update of file attributes when files have a valid EVM signature,
 * except in the case of them having an immutable portable signature.
+9 −6
Original line number Diff line number Diff line
@@ -43,12 +43,10 @@ static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
		else if (inode > iint->inode)
			n = n->rb_right;
		else
			break;
			return iint;
	}
	if (!n)
		return NULL;

	return iint;
	return NULL;
}

/*
@@ -113,10 +111,15 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
		parent = *p;
		test_iint = rb_entry(parent, struct integrity_iint_cache,
				     rb_node);
		if (inode < test_iint->inode)
		if (inode < test_iint->inode) {
			p = &(*p)->rb_left;
		else
		} else if (inode > test_iint->inode) {
			p = &(*p)->rb_right;
		} else {
			write_unlock(&integrity_iint_lock);
			kmem_cache_free(iint_cache, iint);
			return test_iint;
		}
	}

	iint->inode = inode;
+6 −3
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@
#include <linux/fs.h>
#include <linux/xattr.h>
#include <linux/evm.h>
#include <linux/iversion.h>
#include <linux/fsverity.h>

#include "ima.h"
@@ -246,10 +245,11 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
	struct inode *inode = file_inode(file);
	const char *filename = file->f_path.dentry->d_name.name;
	struct ima_max_digest_data hash;
	struct kstat stat;
	int result = 0;
	int length;
	void *tmpbuf;
	u64 i_version;
	u64 i_version = 0;

	/*
	 * Always collect the modsig, because IMA might have already collected
@@ -268,7 +268,10 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
	 * to an initial measurement/appraisal/audit, but was modified to
	 * assume the file changed.
	 */
	i_version = inode_query_iversion(inode);
	result = vfs_getattr_nosec(&file->f_path, &stat, STATX_CHANGE_COOKIE,
				   AT_STATX_SYNC_AS_STAT);
	if (!result && (stat.result_mask & STATX_CHANGE_COOKIE))
		i_version = stat.change_cookie;
	hash.hdr.algo = algo;
	hash.hdr.length = hash_digest_size[algo];

+8 −4
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@
#include <linux/slab.h>
#include <linux/xattr.h>
#include <linux/ima.h>
#include <linux/iversion.h>
#include <linux/fs.h>

#include "ima.h"
@@ -164,11 +163,16 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,

	mutex_lock(&iint->mutex);
	if (atomic_read(&inode->i_writecount) == 1) {
		struct kstat stat;

		update = test_and_clear_bit(IMA_UPDATE_XATTR,
					    &iint->atomic_flags);
		if (!IS_I_VERSION(inode) ||
		    !inode_eq_iversion(inode, iint->version) ||
		    (iint->flags & IMA_NEW_FILE)) {
		if ((iint->flags & IMA_NEW_FILE) ||
		    vfs_getattr_nosec(&file->f_path, &stat,
				      STATX_CHANGE_COOKIE,
				      AT_STATX_SYNC_AS_STAT) ||
		    !(stat.result_mask & STATX_CHANGE_COOKIE) ||
		    stat.change_cookie != iint->version) {
			iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
			iint->measured_pcrs = 0;
			if (update)
Loading