#endif /* CONFIG_IMA_APPRAISE */
#ifdef CONFIG_IMA_APPRAISE_MODSIG
-bool ima_hook_supports_modsig(enum ima_hooks func);
int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
struct modsig **modsig);
void ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size);
u32 *data_len);
void ima_free_modsig(struct modsig *modsig);
#else
-static inline bool ima_hook_supports_modsig(enum ima_hooks func)
-{
- return false;
-}
-
static inline int ima_read_modsig(enum ima_hooks func, const void *buf,
loff_t buf_len, struct modsig **modsig)
{
u8 raw_pkcs7[];
};
-/**
- * ima_hook_supports_modsig - can the policy allow modsig for this hook?
- *
- * modsig is only supported by hooks using ima_post_read_file(), because only
- * they preload the contents of the file in a buffer. FILE_CHECK does that in
- * some cases, but not when reached from vfs_open(). POLICY_CHECK can support
- * it, but it's not useful in practice because it's a text file so deny.
- */
-bool ima_hook_supports_modsig(enum ima_hooks func)
-{
- switch (func) {
- case KEXEC_KERNEL_CHECK:
- case KEXEC_INITRAMFS_CHECK:
- case MODULE_CHECK:
- return true;
- default:
- return false;
- }
-}
-
/*
* ima_read_modsig - Read modsig from buf.
*
static bool ima_validate_rule(struct ima_rule_entry *entry)
{
- /* Ensure that the action is set */
+ /* Ensure that the action is set and is compatible with the flags */
if (entry->action == UNKNOWN)
return false;
+ if (entry->action != MEASURE && entry->flags & IMA_PCR)
+ return false;
+
+ if (entry->action != APPRAISE &&
+ entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | IMA_CHECK_BLACKLIST))
+ return false;
+
+ /*
+ * The IMA_FUNC bit must be set if and only if there's a valid hook
+ * function specified, and vice versa. Enforcing this property allows
+ * for the NONE case below to validate a rule without an explicit hook
+ * function.
+ */
+ if (((entry->flags & IMA_FUNC) && entry->func == NONE) ||
+ (!(entry->flags & IMA_FUNC) && entry->func != NONE))
+ return false;
+
/*
* Ensure that the hook function is compatible with the other
* components of the rule
case BPRM_CHECK:
case CREDS_CHECK:
case POST_SETATTR:
- case MODULE_CHECK:
case FIRMWARE_CHECK:
+ case POLICY_CHECK:
+ if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
+ IMA_UID | IMA_FOWNER | IMA_FSUUID |
+ IMA_INMASK | IMA_EUID | IMA_PCR |
+ IMA_FSNAME | IMA_DIGSIG_REQUIRED |
+ IMA_PERMIT_DIRECTIO))
+ return false;
+
+ break;
+ case MODULE_CHECK:
case KEXEC_KERNEL_CHECK:
case KEXEC_INITRAMFS_CHECK:
- case POLICY_CHECK:
- /* Validation of these hook functions is in ima_parse_rule() */
+ if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC |
+ IMA_UID | IMA_FOWNER | IMA_FSUUID |
+ IMA_INMASK | IMA_EUID | IMA_PCR |
+ IMA_FSNAME | IMA_DIGSIG_REQUIRED |
+ IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED |
+ IMA_CHECK_BLACKLIST))
+ return false;
+
break;
case KEXEC_CMDLINE:
if (entry->action & ~(MEASURE | DONT_MEASURE))
keyrings_len = strlen(args[0].from) + 1;
if ((entry->keyrings) ||
- (entry->func != KEY_CHECK) ||
(keyrings_len < 2)) {
result = -EINVAL;
break;
AUDIT_SUBJ_TYPE);
break;
case Opt_appraise_type:
- if (entry->action != APPRAISE) {
- result = -EINVAL;
- break;
- }
-
ima_log_string(ab, "appraise_type", args[0].from);
if ((strcmp(args[0].from, "imasig")) == 0)
entry->flags |= IMA_DIGSIG_REQUIRED;
- else if (ima_hook_supports_modsig(entry->func) &&
+ else if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
strcmp(args[0].from, "imasig|modsig") == 0)
entry->flags |= IMA_DIGSIG_REQUIRED |
IMA_MODSIG_ALLOWED;
result = -EINVAL;
break;
case Opt_appraise_flag:
- if (entry->action != APPRAISE) {
- result = -EINVAL;
- break;
- }
-
ima_log_string(ab, "appraise_flag", args[0].from);
if (IS_ENABLED(CONFIG_IMA_APPRAISE_MODSIG) &&
strstr(args[0].from, "blacklist"))
entry->flags |= IMA_PERMIT_DIRECTIO;
break;
case Opt_pcr:
- if (entry->action != MEASURE) {
- result = -EINVAL;
- break;
- }
ima_log_string(ab, "pcr", args[0].from);
result = kstrtoint(args[0].from, 10, &entry->pcr);