From: Roberto Sassu roberto.sassu@huawei.com
euleros inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7QZ2M CVE: NA
-------------------------------------------------
This patch introduces a new hook called DIGEST_LIST_CHECK to measure and appraise digest lists in addition to executables and shared libraries, without including the FILE_CHECK hook in the IMA policy.
Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Tianxing Zhang zhangtianxing3@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: zhoushuiqing zhoushuiqing2@huawei.com --- security/integrity/ima/ima.h | 25 +++++++++++++++++++++++++ security/integrity/ima/ima_main.c | 5 +++++ security/integrity/ima/ima_policy.c | 18 ++++++++++++++++++ 3 files changed, 48 insertions(+)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 42ce87c2d..aeabdb45c 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -189,6 +189,7 @@ static inline unsigned int ima_hash_key(u8 *digest) return (digest[0] | digest[1] << 8) % IMA_MEASURE_HTABLE_SIZE; }
+#ifdef CONFIG_IMA_DIGEST_LIST #define __ima_hooks(hook) \ hook(NONE, none) \ hook(FILE_CHECK, file) \ @@ -206,7 +207,28 @@ static inline unsigned int ima_hash_key(u8 *digest) hook(KEY_CHECK, key) \ hook(CRITICAL_DATA, critical_data) \ hook(SETXATTR_CHECK, setxattr_check) \ + hook(DIGEST_LIST_CHECK, digest_list) \ hook(MAX_CHECK, none) +#else +#define __ima_hooks(hook) \ + hook(NONE, none) \ + hook(FILE_CHECK, file) \ + hook(MMAP_CHECK, mmap) \ + hook(MMAP_CHECK_REQPROT, mmap_reqprot) \ + hook(BPRM_CHECK, bprm) \ + hook(CREDS_CHECK, creds) \ + hook(POST_SETATTR, post_setattr) \ + hook(MODULE_CHECK, module) \ + hook(FIRMWARE_CHECK, firmware) \ + hook(KEXEC_KERNEL_CHECK, kexec_kernel) \ + hook(KEXEC_INITRAMFS_CHECK, kexec_initramfs) \ + hook(POLICY_CHECK, policy) \ + hook(KEXEC_CMDLINE, kexec_cmdline) \ + hook(KEY_CHECK, key) \ + hook(CRITICAL_DATA, critical_data) \ + hook(SETXATTR_CHECK, setxattr_check) \ + hook(MAX_CHECK, none) +#endif
#define __ima_hook_enumify(ENUM, str) ENUM, #define __ima_stringify(arg) (#arg) @@ -313,6 +335,9 @@ int ima_policy_show(struct seq_file *m, void *v); #define IMA_APPRAISE_FIRMWARE 0x10 #define IMA_APPRAISE_POLICY 0x20 #define IMA_APPRAISE_KEXEC 0x40 +#ifdef CONFIG_IMA_DIGEST_LIST +#define IMA_APPRAISE_DIGEST_LIST 0x80 +#endif
#ifdef CONFIG_IMA_APPRAISE int ima_check_blacklist(struct integrity_iint_cache *iint, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 64e539fb2..e40975b2c 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -832,7 +832,12 @@ const int read_idmap[READING_MAX_ID] = { [READING_MODULE] = MODULE_CHECK, [READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK, [READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK, +#ifdef CONFIG_IMA_DIGEST_LIST + [READING_POLICY] = POLICY_CHECK, + [READING_DIGEST_LIST] = DIGEST_LIST_CHECK +#else [READING_POLICY] = POLICY_CHECK +#endif };
/** diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 3ca8b7348..9d9290b63 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -188,6 +188,9 @@ static struct ima_rule_entry default_measurement_rules[] __ro_after_init = { {.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC}, {.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC}, {.action = MEASURE, .func = POLICY_CHECK, .flags = IMA_FUNC}, +#ifdef CONFIG_IMA_DIGEST_LIST + {.action = MEASURE, .func = DIGEST_LIST_CHECK, .flags = IMA_FUNC}, +#endif };
static struct ima_rule_entry default_appraise_rules[] __ro_after_init = { @@ -247,6 +250,10 @@ static struct ima_rule_entry secure_boot_rules[] __ro_after_init = { .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, {.action = APPRAISE, .func = POLICY_CHECK, .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, +#ifdef CONFIG_IMA_DIGEST_LIST + {.action = APPRAISE, .func = DIGEST_LIST_CHECK, + .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, +#endif };
static struct ima_rule_entry critical_data_rules[] __ro_after_init = { @@ -855,6 +862,10 @@ static int ima_appraise_flag(enum ima_hooks func) return IMA_APPRAISE_POLICY; else if (func == KEXEC_KERNEL_CHECK) return IMA_APPRAISE_KEXEC; +#ifdef CONFIG_IMA_DIGEST_LIST + else if (func == DIGEST_LIST_CHECK) + return IMA_APPRAISE_DIGEST_LIST; +#endif return 0; }
@@ -1273,6 +1284,9 @@ static bool ima_validate_rule(struct ima_rule_entry *entry) case POST_SETATTR: case FIRMWARE_CHECK: case POLICY_CHECK: +#ifdef CONFIG_IMA_DIGEST_LIST + case DIGEST_LIST_CHECK: +#endif if (entry->flags & ~(IMA_FUNC | IMA_MASK | IMA_FSMAGIC | IMA_UID | IMA_FOWNER | IMA_FSUUID | IMA_INMASK | IMA_EUID | IMA_PCR | @@ -1529,6 +1543,10 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->func = CRITICAL_DATA; else if (strcmp(args[0].from, "SETXATTR_CHECK") == 0) entry->func = SETXATTR_CHECK; +#ifdef CONFIG_IMA_DIGEST_LIST + else if (strcmp(args[0].from, "DIGEST_LIST_CHECK") == 0) + entry->func = DIGEST_LIST_CHECK; +#endif else result = -EINVAL; if (!result)