Skip to content

Commit de4c44a

Browse files
committed
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>
1 parent 64c658f commit de4c44a

4 files changed

Lines changed: 24 additions & 16 deletions

File tree

Documentation/ABI/testing/ima_policy

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ Description:
5353
where 'imasig' is the original or the signature
5454
format v2.
5555
where 'modsig' is an appended signature,
56-
where 'sigv3' is the signature format v3. (Currently
57-
limited to fsverity digest based signatures
58-
stored in security.ima xattr. Requires
59-
specifying "digest_type=verity" first.)
56+
where 'sigv3' is the signature format v3.
6057

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

186+
Example of a regular IMA file hash 'appraise' rule requiring
187+
signature version 3 format stored in security.ima xattr.
188+
189+
appraise func=BPRM_CHECK appraise_type=sigv3
190+
189191
All of these policy rules could, for example, be constrained
190192
either based on a filesystem's UUID (fsuuid) or based on LSM
191193
labels.

security/integrity/ima/ima.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ struct ima_kexec_hdr {
145145
#define IMA_DIGSIG_REQUIRED 0x01000000
146146
#define IMA_PERMIT_DIRECTIO 0x02000000
147147
#define IMA_NEW_FILE 0x04000000
148+
#define IMA_SIGV3_REQUIRED 0x08000000
148149
#define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
149150
#define IMA_MODSIG_ALLOWED 0x20000000
150151
#define IMA_CHECK_BLACKLIST 0x40000000

security/integrity/ima/ima_appraise.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,13 @@ static int xattr_verify(enum ima_hooks func, struct ima_iint_cache *iint,
302302
*status = INTEGRITY_FAIL;
303303
break;
304304
}
305+
306+
if ((iint->flags & IMA_SIGV3_REQUIRED) && sig->version != 3) {
307+
*cause = "IMA-sigv3-required";
308+
*status = INTEGRITY_FAIL;
309+
break;
310+
}
311+
305312
rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
306313
(const char *)xattr_value,
307314
xattr_len,

security/integrity/ima/ima_policy.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
12981298
IMA_GID | IMA_EGID |
12991299
IMA_FGROUP | IMA_DIGSIG_REQUIRED |
13001300
IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS |
1301-
IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED))
1301+
IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED |
1302+
IMA_SIGV3_REQUIRED))
13021303
return false;
13031304

13041305
break;
@@ -1833,9 +1834,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
18331834
break;
18341835
case Opt_digest_type:
18351836
ima_log_string(ab, "digest_type", args[0].from);
1836-
if (entry->flags & IMA_DIGSIG_REQUIRED)
1837-
result = -EINVAL;
1838-
else if ((strcmp(args[0].from, "verity")) == 0)
1837+
if ((strcmp(args[0].from, "verity")) == 0)
18391838
entry->flags |= IMA_VERITY_REQUIRED;
18401839
else
18411840
result = -EINVAL;
@@ -1849,14 +1848,13 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
18491848
else
18501849
entry->flags |= IMA_DIGSIG_REQUIRED | IMA_CHECK_BLACKLIST;
18511850
} else if (strcmp(args[0].from, "sigv3") == 0) {
1852-
/* Only fsverity supports sigv3 for now */
1853-
if (entry->flags & IMA_VERITY_REQUIRED)
1854-
entry->flags |= IMA_DIGSIG_REQUIRED | IMA_CHECK_BLACKLIST;
1855-
else
1856-
result = -EINVAL;
1851+
entry->flags |= IMA_SIGV3_REQUIRED |
1852+
IMA_DIGSIG_REQUIRED |
1853+
IMA_CHECK_BLACKLIST;
18571854
} else if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
18581855
strcmp(args[0].from, "imasig|modsig") == 0) {
1859-
if (entry->flags & IMA_VERITY_REQUIRED)
1856+
if ((entry->flags & IMA_VERITY_REQUIRED) ||
1857+
(entry->flags & IMA_SIGV3_REQUIRED))
18601858
result = -EINVAL;
18611859
else
18621860
entry->flags |= IMA_DIGSIG_REQUIRED |
@@ -1941,7 +1939,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
19411939

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

0 commit comments

Comments
 (0)