Commit 55dbb6b0 authored by zgzxx's avatar zgzxx
Browse files

ima: digest list new support modsig

euleros inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I967Z0


CVE: NA

-----------------------------------------

ima switch the signature, added support for modsig.
1.IMA digest list file verification supports the modsig mode.
2.IMA digest list supports for appending modsig siganture.
3.When the IMA digest list check is configured for the IMA
  policy, the modsig check is enabled by default.

Signed-off-by: default avatarzhangguangzhi <zhangguangzhi3@huawei.com>
parent 81cc23e7
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -648,7 +648,8 @@ int ima_appraise_measurement(enum ima_hooks func,
		 * are signed or found in a digest list (immutable)
		 */
		if (func == DIGEST_LIST_CHECK || ima_current_is_parser()) {
			if (xattr_value->type == EVM_IMA_XATTR_DIGSIG)
			if (try_modsig ||
			    xattr_value->type == EVM_IMA_XATTR_DIGSIG)
				break;
			if (found_digest &&
			    ima_digest_is_immutable(found_digest))
+31 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/xattr.h>
#include <linux/sched/mm.h>
#include <linux/magic.h>
#include <linux/module_signature.h>

#include "ima.h"
#include "ima_digest_list.h"
@@ -152,6 +153,25 @@ static void ima_del_digest_data_entry(u8 *digest, enum hash_algo algo,
	kfree(d);
}

static size_t ima_get_compact_list_sig_len(loff_t size, void *buf)
{
	const size_t marker_len = strlen(MODULE_SIG_STRING);
	const struct module_signature *sig;
	const void *p;

	if (size <= marker_len + sizeof(*sig))
		return 0;

	p = buf + size - marker_len;

	if (memcmp(p, MODULE_SIG_STRING, marker_len))
		return 0;

	sig = (const struct module_signature *)(p - sizeof(*sig));

	return be32_to_cpu(sig->sig_len) + marker_len + sizeof(*sig);
}

/***********************
 * Compact list parser *
 ***********************/
@@ -172,10 +192,19 @@ int ima_parse_compact_list(loff_t size, void *buf, int op)
	struct compact_list_hdr *hdr;
	size_t digest_len;
	int ret = 0, i;
	ssize_t sig_len;

	if (!(ima_digest_list_actions & ima_policy_flag))
		return -EACCES;

	sig_len = ima_get_compact_list_sig_len(size, buf);
	if (sig_len >= size) {
		pr_err("compact list, invalid signature\n");
		return -EINVAL;
	}

	bufendp -= sig_len;

	while (bufp < bufendp) {
		if (bufp + sizeof(*hdr) > bufendp) {
			pr_err("compact list, invalid data\n");
@@ -235,7 +264,7 @@ int ima_parse_compact_list(loff_t size, void *buf, int op)
		}
	}

	return bufp - buf;
	return bufp - buf + sig_len;
}

/***************************
@@ -269,8 +298,7 @@ void ima_check_measured_appraised(struct file *file)
	}

	if ((ima_digest_list_actions & IMA_APPRAISE) &&
	    (!(iint->flags & IMA_APPRAISED) ||
	    !test_bit(IMA_DIGSIG, &iint->atomic_flags))) {
	    (!(iint->flags & IMA_APPRAISED))) {
		pr_err("%s not appraised, disabling digest lists lookup for appraisal\n",
			file_dentry(file)->d_name.name);
		ima_digest_list_actions &= ~IMA_APPRAISE;
+3 −2
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = {
	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
#ifdef CONFIG_IMA_DIGEST_LIST
	{.action = APPRAISE, .func = DIGEST_LIST_CHECK,
	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED},
	 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED},
#endif
};

@@ -1418,7 +1418,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
				     IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS |
#ifdef CONFIG_IMA_DIGEST_LIST
				     IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED |
				     IMA_META_IMMUTABLE_REQUIRED | IMA_PARSER))
				     IMA_META_IMMUTABLE_REQUIRED | IMA_PARSER |
				     IMA_MODSIG_ALLOWED))
#else
				     IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED))
#endif