Commit de4c44a7 authored by Mimi Zohar's avatar Mimi Zohar
Browse files

ima: add support to require IMA sigv3 signatures



Defining a policy rule with the "appraise_type=imasig" option allows
either v2 or v3 signatures. Defining an IMA appraise rule with the
"appraise_type=sigv3" option requires a file sigv3 signature.

Define a new appraise type: IMA_SIGV3_REQUIRED

Example: appraise func=BPRM_CHECK appraise_type=sigv3

Tested-by: default avatarStefan Berger <stefanb@linux.ibm.com>
Acked-by: default avatarEric Biggers <ebiggers@kernel.org>
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent 64c658f3
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -53,10 +53,7 @@ Description:
			    where 'imasig' is the original or the signature
				format v2.
			    where 'modsig' is an appended signature,
			    where 'sigv3' is the signature format v3. (Currently
				limited to fsverity digest based signatures
				stored in security.ima xattr. Requires
				specifying "digest_type=verity" first.)
			    where 'sigv3' is the signature format v3.

			appraise_flag:= [check_blacklist] (deprecated)
			Setting the check_blacklist flag is no longer necessary.
@@ -186,6 +183,11 @@ Description:
			appraise func=BPRM_CHECK digest_type=verity \
				appraise_type=sigv3

		Example of a regular IMA file hash 'appraise' rule requiring
		signature version 3 format stored in security.ima xattr.

			appraise func=BPRM_CHECK appraise_type=sigv3

		All of these policy rules could, for example, be constrained
		either based on a filesystem's UUID (fsuuid) or based on LSM
		labels.
+1 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ struct ima_kexec_hdr {
#define IMA_DIGSIG_REQUIRED	0x01000000
#define IMA_PERMIT_DIRECTIO	0x02000000
#define IMA_NEW_FILE		0x04000000
#define IMA_SIGV3_REQUIRED	0x08000000
#define IMA_FAIL_UNVERIFIABLE_SIGS	0x10000000
#define IMA_MODSIG_ALLOWED	0x20000000
#define IMA_CHECK_BLACKLIST	0x40000000
+7 −0
Original line number Diff line number Diff line
@@ -302,6 +302,13 @@ static int xattr_verify(enum ima_hooks func, struct ima_iint_cache *iint,
			*status = INTEGRITY_FAIL;
			break;
		}

		if ((iint->flags & IMA_SIGV3_REQUIRED) && sig->version != 3) {
			*cause = "IMA-sigv3-required";
			*status = INTEGRITY_FAIL;
			break;
		}

		rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
					     (const char *)xattr_value,
					     xattr_len,
+10 −12
Original line number Diff line number Diff line
@@ -1298,7 +1298,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
				     IMA_GID | IMA_EGID |
				     IMA_FGROUP | IMA_DIGSIG_REQUIRED |
				     IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS |
				     IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED))
				     IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED |
				     IMA_SIGV3_REQUIRED))
			return false;

		break;
@@ -1833,9 +1834,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
			break;
		case Opt_digest_type:
			ima_log_string(ab, "digest_type", args[0].from);
			if (entry->flags & IMA_DIGSIG_REQUIRED)
				result = -EINVAL;
			else if ((strcmp(args[0].from, "verity")) == 0)
			if ((strcmp(args[0].from, "verity")) == 0)
				entry->flags |= IMA_VERITY_REQUIRED;
			else
				result = -EINVAL;
@@ -1849,14 +1848,13 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
				else
					entry->flags |= IMA_DIGSIG_REQUIRED | IMA_CHECK_BLACKLIST;
			} else if (strcmp(args[0].from, "sigv3") == 0) {
				/* Only fsverity supports sigv3 for now */
				if (entry->flags & IMA_VERITY_REQUIRED)
					entry->flags |= IMA_DIGSIG_REQUIRED | IMA_CHECK_BLACKLIST;
				else
					result = -EINVAL;
				entry->flags |= IMA_SIGV3_REQUIRED |
					IMA_DIGSIG_REQUIRED |
					IMA_CHECK_BLACKLIST;
			} else if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
				 strcmp(args[0].from, "imasig|modsig") == 0) {
				if (entry->flags & IMA_VERITY_REQUIRED)
				if ((entry->flags & IMA_VERITY_REQUIRED) ||
				    (entry->flags & IMA_SIGV3_REQUIRED))
					result = -EINVAL;
				else
					entry->flags |= IMA_DIGSIG_REQUIRED |
@@ -1941,7 +1939,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)

	/* d-ngv2 template field recommended for unsigned fs-verity digests */
	if (!result && entry->action == MEASURE &&
	    entry->flags & IMA_VERITY_REQUIRED) {
	    (entry->flags & IMA_VERITY_REQUIRED)) {
		template_desc = entry->template ? entry->template :
						  ima_template_desc_current();
		check_template_field(template_desc, "d-ngv2",
@@ -2309,7 +2307,7 @@ int ima_policy_show(struct seq_file *m, void *v)
	if (entry->template)
		seq_printf(m, "template=%s ", entry->template->name);
	if (entry->flags & IMA_DIGSIG_REQUIRED) {
		if (entry->flags & IMA_VERITY_REQUIRED)
		if (entry->flags & IMA_SIGV3_REQUIRED)
			seq_puts(m, "appraise_type=sigv3 ");
		else if (entry->flags & IMA_MODSIG_ALLOWED)
			seq_puts(m, "appraise_type=imasig|modsig ");