Commit d0e91e40 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull integrity updates from Mimi Zohar:
 "Just two bug fixes: IMA's detecting scripts (bprm_creds_for_exec), and
  calculating the EVM HMAC"

* tag 'integrity-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  evm: Use ordered xattrs list to calculate HMAC in evm_init_hmac()
  ima: Fix stack-out-of-bounds in is_bprm_creds_for_exec()
parents 146fa666 0496fc9c
Loading
Loading
Loading
Loading
+10 −4
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ int evm_init_hmac(struct inode *inode, const struct xattr *xattrs,
{
	struct shash_desc *desc;
	const struct xattr *xattr;
	struct xattr_list *xattr_entry;

	desc = init_desc(EVM_XATTR_HMAC, HASH_ALGO_SHA1);
	if (IS_ERR(desc)) {
@@ -408,11 +409,16 @@ int evm_init_hmac(struct inode *inode, const struct xattr *xattrs,
		return PTR_ERR(desc);
	}

	list_for_each_entry_lockless(xattr_entry, &evm_config_xattrnames,
				     list) {
		for (xattr = xattrs; xattr->name; xattr++) {
		if (!evm_protected_xattr(xattr->name))
			if (strcmp(xattr_entry->name +
				   XATTR_SECURITY_PREFIX_LEN, xattr->name) != 0)
				continue;

		crypto_shash_update(desc, xattr->value, xattr->value_len);
			crypto_shash_update(desc, xattr->value,
					    xattr->value_len);
		}
	}

	hmac_add_misc(desc, inode, EVM_XATTR_HMAC, hmac_val);
+4 −2
Original line number Diff line number Diff line
@@ -441,7 +441,8 @@ int ima_check_blacklist(struct ima_iint_cache *iint,
int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint,
			     struct file *file, const unsigned char *filename,
			     struct evm_ima_xattr_data *xattr_value,
			     int xattr_len, const struct modsig *modsig);
			     int xattr_len, const struct modsig *modsig,
			     bool bprm_is_check);
int ima_must_appraise(struct mnt_idmap *idmap, struct inode *inode,
		      int mask, enum ima_hooks func);
void ima_update_xattr(struct ima_iint_cache *iint, struct file *file);
@@ -466,7 +467,8 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
					   const unsigned char *filename,
					   struct evm_ima_xattr_data *xattr_value,
					   int xattr_len,
					   const struct modsig *modsig)
					   const struct modsig *modsig,
					   bool bprm_is_check)
{
	return INTEGRITY_UNKNOWN;
}
+3 −13
Original line number Diff line number Diff line
@@ -470,17 +470,6 @@ int ima_check_blacklist(struct ima_iint_cache *iint,
	return rc;
}

static bool is_bprm_creds_for_exec(enum ima_hooks func, struct file *file)
{
	struct linux_binprm *bprm;

	if (func == BPRM_CHECK) {
		bprm = container_of(&file, struct linux_binprm, file);
		return bprm->is_check;
	}
	return false;
}

/*
 * ima_appraise_measurement - appraise file measurement
 *
@@ -492,7 +481,8 @@ static bool is_bprm_creds_for_exec(enum ima_hooks func, struct file *file)
int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint,
			     struct file *file, const unsigned char *filename,
			     struct evm_ima_xattr_data *xattr_value,
			     int xattr_len, const struct modsig *modsig)
			     int xattr_len, const struct modsig *modsig,
			     bool bprm_is_check)
{
	static const char op[] = "appraise_data";
	int audit_msgno = AUDIT_INTEGRITY_DATA;
@@ -514,7 +504,7 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint,
	 * of the script interpreter(userspace). Differentiate kernel and
	 * userspace enforced integrity audit messages.
	 */
	if (is_bprm_creds_for_exec(func, file))
	if (bprm_is_check)
		audit_msgno = AUDIT_INTEGRITY_USERSPACE;

	/* If reading the xattr failed and there's no modsig, error out. */
+13 −9
Original line number Diff line number Diff line
@@ -236,7 +236,8 @@ static void ima_file_free(struct file *file)
static int process_measurement(struct file *file, const struct cred *cred,
			       struct lsm_prop *prop, char *buf, loff_t size,
			       int mask, enum ima_hooks func,
			       enum kernel_read_file_id read_id)
			       enum kernel_read_file_id read_id,
			       bool bprm_is_check)
{
	struct inode *real_inode, *inode = file_inode(file);
	struct ima_iint_cache *iint = NULL;
@@ -426,7 +427,8 @@ static int process_measurement(struct file *file, const struct cred *cred,
			inode_lock(inode);
			rc = ima_appraise_measurement(func, iint, file,
						      pathname, xattr_value,
						      xattr_len, modsig);
						      xattr_len, modsig,
						      bprm_is_check);
			inode_unlock(inode);
		}
		if (!rc)
@@ -493,14 +495,15 @@ static int ima_file_mmap(struct file *file, unsigned long reqprot,

	if (reqprot & PROT_EXEC) {
		ret = process_measurement(file, current_cred(), &prop, NULL,
					  0, MAY_EXEC, MMAP_CHECK_REQPROT, 0);
					  0, MAY_EXEC, MMAP_CHECK_REQPROT, 0,
					  false);
		if (ret)
			return ret;
	}

	if (prot & PROT_EXEC)
		return process_measurement(file, current_cred(), &prop, NULL,
					   0, MAY_EXEC, MMAP_CHECK, 0);
					   0, MAY_EXEC, MMAP_CHECK, 0, false);

	return 0;
}
@@ -584,7 +587,8 @@ static int ima_bprm_check(struct linux_binprm *bprm)

	security_current_getlsmprop_subj(&prop);
	return process_measurement(bprm->file, current_cred(),
				   &prop, NULL, 0, MAY_EXEC, BPRM_CHECK, 0);
				   &prop, NULL, 0, MAY_EXEC, BPRM_CHECK, 0,
				   bprm->is_check);
}

/**
@@ -614,7 +618,7 @@ static int ima_creds_check(struct linux_binprm *bprm, const struct file *file)

	security_current_getlsmprop_subj(&prop);
	return process_measurement((struct file *)file, bprm->cred, &prop, NULL,
				   0, MAY_EXEC, CREDS_CHECK, 0);
				   0, MAY_EXEC, CREDS_CHECK, 0, false);
}

/**
@@ -662,7 +666,7 @@ static int ima_file_check(struct file *file, int mask)
	security_current_getlsmprop_subj(&prop);
	return process_measurement(file, current_cred(), &prop, NULL, 0,
				   mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
					   MAY_APPEND), FILE_CHECK, 0);
					   MAY_APPEND), FILE_CHECK, 0, false);
}

static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf,
@@ -881,7 +885,7 @@ static int ima_read_file(struct file *file, enum kernel_read_file_id read_id,
	func = read_idmap[read_id] ?: FILE_CHECK;
	security_current_getlsmprop_subj(&prop);
	return process_measurement(file, current_cred(), &prop, NULL, 0,
				   MAY_READ, func, 0);
				   MAY_READ, func, 0, false);
}

const int read_idmap[READING_MAX_ID] = {
@@ -925,7 +929,7 @@ static int ima_post_read_file(struct file *file, char *buf, loff_t size,
	func = read_idmap[read_id] ?: FILE_CHECK;
	security_current_getlsmprop_subj(&prop);
	return process_measurement(file, current_cred(), &prop, buf, size,
				   MAY_READ, func, read_id);
				   MAY_READ, func, read_id, false);
}

/**