diff options
| author | Mimi Zohar <zohar@linux.ibm.com> | 2026-03-10 09:16:25 -0400 |
|---|---|---|
| committer | Mimi Zohar <zohar@linux.ibm.com> | 2026-04-01 10:16:30 -0400 |
| commit | de4c44a7f559ceae19f7a70febf49e87bdfb125c (patch) | |
| tree | b2fbedfdfb0ec379301bf9b105191bd8def45ba1 /security | |
| parent | 64c658f358ec6ed6e992d4cf05482eaa2ab4b1a4 (diff) | |
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: Stefan Berger <stefanb@linux.ibm.com>
Acked-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
Diffstat (limited to 'security')
| -rw-r--r-- | security/integrity/ima/ima.h | 1 | ||||
| -rw-r--r-- | security/integrity/ima/ima_appraise.c | 7 | ||||
| -rw-r--r-- | security/integrity/ima/ima_policy.c | 22 |
3 files changed, 18 insertions, 12 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 0eea02ff04df..69e9bf0b82c6 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -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 diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 8f182d808b09..de963b9f3634 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -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, diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index bf2d7ba4c14a..f7f940a76922 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -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 "); |
