]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ima: add support to require IMA sigv3 signatures
authorMimi Zohar <zohar@linux.ibm.com>
Tue, 10 Mar 2026 13:16:25 +0000 (09:16 -0400)
committerMimi Zohar <zohar@linux.ibm.com>
Wed, 1 Apr 2026 14:16:30 +0000 (10:16 -0400)
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>
Documentation/ABI/testing/ima_policy
security/integrity/ima/ima.h
security/integrity/ima/ima_appraise.c
security/integrity/ima/ima_policy.c

index d4b3696a9efb3ea7a67de85be30675be8bfe4e3f..19258471b7b26b2c42c1ab2d11b4fd630b2e6f81 100644 (file)
@@ -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.
index 0eea02ff04df6e9abb3d5f825278f21314311675..69e9bf0b82c655fd139dffc6e7d33192cdcec7a8 100644 (file)
@@ -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
index 8f182d808b096d7f03b6b64222ede7afb0d16d79..de963b9f3634470bc79145ad13f602c35c20a00e 100644 (file)
@@ -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,
index bf2d7ba4c14a9c948f76a82e8e14394e23b9b687..f7f940a7692234d447fdb99e3a75695e5bb57674 100644 (file)
@@ -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 ");