Commit 717e6eb4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull integrity updates from Mimi Zohar:
 "Aside from the one cleanup, the other changes are bug fixes:

  Cleanup:

   - Include missing iMac Pro 2017 in list of Macs with T2 security chip

  Bug fixes:

   - Improper instantiation of "encrypted" keys with user provided data

   - Not handling delay in updating LSM label based IMA policy rules
     (-ESTALE)

   - IMA and integrity memory leaks on error paths

   - CONFIG_IMA_DEFAULT_HASH_SM3 hash algorithm renamed"

* tag 'integrity-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: Fix hash dependency to correct algorithm
  ima: Fix misuse of dereference of pointer in template_desc_init_fields()
  integrity: Fix memory leakage in keyring allocation error path
  ima: Fix memory leak in __ima_inode_hash()
  ima: Handle -ESTALE returned by ima_filter_rule_match()
  ima: Simplify ima_lsm_copy_rule
  ima: Fix a potential NULL pointer access in ima_restore_measurement_list
  efi: Add iMac Pro 2017 to uefi skip cert quirk
  KEYS: encrypted: fix key instantiation with user-provided data
parents 8fa37a68 b6018af4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -350,7 +350,8 @@ Load an encrypted key "evm" from saved blob::

Instantiate an encrypted key "evm" using user-provided decrypted data::

    $ keyctl add encrypted evm "new default user:kmk 32 `cat evm_decrypted_data.blob`" @u
    $ evmkey=$(dd if=/dev/urandom bs=1 count=32 | xxd -c32 -p)
    $ keyctl add encrypted evm "new default user:kmk 32 $evmkey" @u
    794890253

    $ keyctl print 794890253
+5 −1
Original line number Diff line number Diff line
@@ -126,6 +126,7 @@ int __init integrity_init_keyring(const unsigned int id)
{
	struct key_restriction *restriction;
	key_perm_t perm;
	int ret;

	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
		| KEY_USR_READ | KEY_USR_SEARCH;
@@ -154,7 +155,10 @@ int __init integrity_init_keyring(const unsigned int id)
		perm |= KEY_USR_WRITE;

out:
	return __integrity_init_keyring(id, perm, restriction);
	ret = __integrity_init_keyring(id, perm, restriction);
	if (ret)
		kfree(restriction);
	return ret;
}

static int __init integrity_add_key(const unsigned int id, const void *data,
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ choice

	config IMA_DEFAULT_HASH_SM3
		bool "SM3"
		depends on CRYPTO_SM3=y
		depends on CRYPTO_SM3_GENERIC=y
endchoice

config IMA_DEFAULT_HASH
+6 −1
Original line number Diff line number Diff line
@@ -544,8 +544,13 @@ static int __ima_inode_hash(struct inode *inode, struct file *file, char *buf,

		rc = ima_collect_measurement(&tmp_iint, file, NULL, 0,
					     ima_hash_algo, NULL);
		if (rc < 0)
		if (rc < 0) {
			/* ima_hash could be allocated in case of failure. */
			if (rc != -ENOMEM)
				kfree(tmp_iint.ima_hash);

			return -EOPNOTSUPP;
		}

		iint = &tmp_iint;
		mutex_lock(&iint->mutex);
+35 −16
Original line number Diff line number Diff line
@@ -398,12 +398,6 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)

		nentry->lsm[i].type = entry->lsm[i].type;
		nentry->lsm[i].args_p = entry->lsm[i].args_p;
		/*
		 * Remove the reference from entry so that the associated
		 * memory will not be freed during a later call to
		 * ima_lsm_free_rule(entry).
		 */
		entry->lsm[i].args_p = NULL;

		ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
				     nentry->lsm[i].args_p,
@@ -417,6 +411,7 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)

static int ima_lsm_update_rule(struct ima_rule_entry *entry)
{
	int i;
	struct ima_rule_entry *nentry;

	nentry = ima_lsm_copy_rule(entry);
@@ -431,7 +426,8 @@ static int ima_lsm_update_rule(struct ima_rule_entry *entry)
	 * references and the entry itself. All other memory references will now
	 * be owned by nentry.
	 */
	ima_lsm_free_rule(entry);
	for (i = 0; i < MAX_LSM_RULES; i++)
		ima_filter_rule_free(entry->lsm[i].rule);
	kfree(entry);

	return 0;
@@ -549,6 +545,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
			    const char *func_data)
{
	int i;
	bool result = false;
	struct ima_rule_entry *lsm_rule = rule;
	bool rule_reinitialized = false;

	if ((rule->flags & IMA_FUNC) &&
	    (rule->func != func && func != POST_SETATTR))
@@ -612,35 +611,55 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
		int rc = 0;
		u32 osid;

		if (!rule->lsm[i].rule) {
			if (!rule->lsm[i].args_p)
		if (!lsm_rule->lsm[i].rule) {
			if (!lsm_rule->lsm[i].args_p)
				continue;
			else
				return false;
		}

retry:
		switch (i) {
		case LSM_OBJ_USER:
		case LSM_OBJ_ROLE:
		case LSM_OBJ_TYPE:
			security_inode_getsecid(inode, &osid);
			rc = ima_filter_rule_match(osid, rule->lsm[i].type,
			rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
						   Audit_equal,
						   rule->lsm[i].rule);
						   lsm_rule->lsm[i].rule);
			break;
		case LSM_SUBJ_USER:
		case LSM_SUBJ_ROLE:
		case LSM_SUBJ_TYPE:
			rc = ima_filter_rule_match(secid, rule->lsm[i].type,
			rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
						   Audit_equal,
						   rule->lsm[i].rule);
						   lsm_rule->lsm[i].rule);
			break;
		default:
			break;
		}
		if (!rc)
			return false;

		if (rc == -ESTALE && !rule_reinitialized) {
			lsm_rule = ima_lsm_copy_rule(rule);
			if (lsm_rule) {
				rule_reinitialized = true;
				goto retry;
			}
	return true;
		}
		if (!rc) {
			result = false;
			goto out;
		}
	}
	result = true;

out:
	if (rule_reinitialized) {
		for (i = 0; i < MAX_LSM_RULES; i++)
			ima_filter_rule_free(lsm_rule->lsm[i].rule);
		kfree(lsm_rule);
	}
	return result;
}

/*
Loading