mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
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>
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 ");
|
||||
|
||||
Reference in New Issue
Block a user