mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02: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:
parent
64c658f358
commit
de4c44a7f5
|
|
@ -53,10 +53,7 @@ Description:
|
||||||
where 'imasig' is the original or the signature
|
where 'imasig' is the original or the signature
|
||||||
format v2.
|
format v2.
|
||||||
where 'modsig' is an appended signature,
|
where 'modsig' is an appended signature,
|
||||||
where 'sigv3' is the signature format v3. (Currently
|
where 'sigv3' is the signature format v3.
|
||||||
limited to fsverity digest based signatures
|
|
||||||
stored in security.ima xattr. Requires
|
|
||||||
specifying "digest_type=verity" first.)
|
|
||||||
|
|
||||||
appraise_flag:= [check_blacklist] (deprecated)
|
appraise_flag:= [check_blacklist] (deprecated)
|
||||||
Setting the check_blacklist flag is no longer necessary.
|
Setting the check_blacklist flag is no longer necessary.
|
||||||
|
|
@ -186,6 +183,11 @@ Description:
|
||||||
appraise func=BPRM_CHECK digest_type=verity \
|
appraise func=BPRM_CHECK digest_type=verity \
|
||||||
appraise_type=sigv3
|
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
|
All of these policy rules could, for example, be constrained
|
||||||
either based on a filesystem's UUID (fsuuid) or based on LSM
|
either based on a filesystem's UUID (fsuuid) or based on LSM
|
||||||
labels.
|
labels.
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,7 @@ struct ima_kexec_hdr {
|
||||||
#define IMA_DIGSIG_REQUIRED 0x01000000
|
#define IMA_DIGSIG_REQUIRED 0x01000000
|
||||||
#define IMA_PERMIT_DIRECTIO 0x02000000
|
#define IMA_PERMIT_DIRECTIO 0x02000000
|
||||||
#define IMA_NEW_FILE 0x04000000
|
#define IMA_NEW_FILE 0x04000000
|
||||||
|
#define IMA_SIGV3_REQUIRED 0x08000000
|
||||||
#define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
|
#define IMA_FAIL_UNVERIFIABLE_SIGS 0x10000000
|
||||||
#define IMA_MODSIG_ALLOWED 0x20000000
|
#define IMA_MODSIG_ALLOWED 0x20000000
|
||||||
#define IMA_CHECK_BLACKLIST 0x40000000
|
#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;
|
*status = INTEGRITY_FAIL;
|
||||||
break;
|
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,
|
rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA,
|
||||||
(const char *)xattr_value,
|
(const char *)xattr_value,
|
||||||
xattr_len,
|
xattr_len,
|
||||||
|
|
|
||||||
|
|
@ -1298,7 +1298,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
|
||||||
IMA_GID | IMA_EGID |
|
IMA_GID | IMA_EGID |
|
||||||
IMA_FGROUP | IMA_DIGSIG_REQUIRED |
|
IMA_FGROUP | IMA_DIGSIG_REQUIRED |
|
||||||
IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS |
|
IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS |
|
||||||
IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED))
|
IMA_CHECK_BLACKLIST | IMA_VERITY_REQUIRED |
|
||||||
|
IMA_SIGV3_REQUIRED))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1833,9 +1834,7 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||||
break;
|
break;
|
||||||
case Opt_digest_type:
|
case Opt_digest_type:
|
||||||
ima_log_string(ab, "digest_type", args[0].from);
|
ima_log_string(ab, "digest_type", args[0].from);
|
||||||
if (entry->flags & IMA_DIGSIG_REQUIRED)
|
if ((strcmp(args[0].from, "verity")) == 0)
|
||||||
result = -EINVAL;
|
|
||||||
else if ((strcmp(args[0].from, "verity")) == 0)
|
|
||||||
entry->flags |= IMA_VERITY_REQUIRED;
|
entry->flags |= IMA_VERITY_REQUIRED;
|
||||||
else
|
else
|
||||||
result = -EINVAL;
|
result = -EINVAL;
|
||||||
|
|
@ -1849,14 +1848,13 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||||
else
|
else
|
||||||
entry->flags |= IMA_DIGSIG_REQUIRED | IMA_CHECK_BLACKLIST;
|
entry->flags |= IMA_DIGSIG_REQUIRED | IMA_CHECK_BLACKLIST;
|
||||||
} else if (strcmp(args[0].from, "sigv3") == 0) {
|
} else if (strcmp(args[0].from, "sigv3") == 0) {
|
||||||
/* Only fsverity supports sigv3 for now */
|
entry->flags |= IMA_SIGV3_REQUIRED |
|
||||||
if (entry->flags & IMA_VERITY_REQUIRED)
|
IMA_DIGSIG_REQUIRED |
|
||||||
entry->flags |= IMA_DIGSIG_REQUIRED | IMA_CHECK_BLACKLIST;
|
IMA_CHECK_BLACKLIST;
|
||||||
else
|
|
||||||
result = -EINVAL;
|
|
||||||
} else if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
|
} else if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
|
||||||
strcmp(args[0].from, "imasig|modsig") == 0) {
|
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;
|
result = -EINVAL;
|
||||||
else
|
else
|
||||||
entry->flags |= IMA_DIGSIG_REQUIRED |
|
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 */
|
/* d-ngv2 template field recommended for unsigned fs-verity digests */
|
||||||
if (!result && entry->action == MEASURE &&
|
if (!result && entry->action == MEASURE &&
|
||||||
entry->flags & IMA_VERITY_REQUIRED) {
|
(entry->flags & IMA_VERITY_REQUIRED)) {
|
||||||
template_desc = entry->template ? entry->template :
|
template_desc = entry->template ? entry->template :
|
||||||
ima_template_desc_current();
|
ima_template_desc_current();
|
||||||
check_template_field(template_desc, "d-ngv2",
|
check_template_field(template_desc, "d-ngv2",
|
||||||
|
|
@ -2309,7 +2307,7 @@ int ima_policy_show(struct seq_file *m, void *v)
|
||||||
if (entry->template)
|
if (entry->template)
|
||||||
seq_printf(m, "template=%s ", entry->template->name);
|
seq_printf(m, "template=%s ", entry->template->name);
|
||||||
if (entry->flags & IMA_DIGSIG_REQUIRED) {
|
if (entry->flags & IMA_DIGSIG_REQUIRED) {
|
||||||
if (entry->flags & IMA_VERITY_REQUIRED)
|
if (entry->flags & IMA_SIGV3_REQUIRED)
|
||||||
seq_puts(m, "appraise_type=sigv3 ");
|
seq_puts(m, "appraise_type=sigv3 ");
|
||||||
else if (entry->flags & IMA_MODSIG_ALLOWED)
|
else if (entry->flags & IMA_MODSIG_ALLOWED)
|
||||||
seq_puts(m, "appraise_type=imasig|modsig ");
|
seq_puts(m, "appraise_type=imasig|modsig ");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user