This patch adds support for measuring and appraising the IMA policy
itself.

Signed-off-by: Mimi Zohar <zo...@linux.vnet.ibm.com>
---
 security/integrity/ima/ima.h        |  1 +
 security/integrity/ima/ima_fs.c     |  9 ++++++++-
 security/integrity/ima/ima_policy.c | 14 ++++++++++++--
 3 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index fc31ba2..e8f111b 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -185,6 +185,7 @@ int ima_policy_show(struct seq_file *m, void *v);
 #define IMA_APPRAISE_LOG       0x04
 #define IMA_APPRAISE_MODULES   0x08
 #define IMA_APPRAISE_FIRMWARE  0x10
+#define IMA_APPRAISE_POLICY    0x20
 
 #ifdef CONFIG_IMA_APPRAISE
 int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index fe8b16b..57c6b2e 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -325,7 +325,14 @@ static ssize_t ima_write_policy(struct file *file, const 
char __user *buf,
 
        if (data[0] == '/')
                result = ima_read_policy(data);
-       else
+       else if (ima_appraise & IMA_APPRAISE_POLICY) {
+               pr_err("IMA: signed policy required\n");
+               integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
+                                   "policy_update", "signed policy required",
+                                   1, 0);
+               if (ima_appraise & IMA_APPRAISE_ENFORCE)
+                       result = -EACCES;
+       } else
                result = ima_parse_add_rule(data);
        mutex_unlock(&ima_write_mutex);
 out_free:
diff --git a/security/integrity/ima/ima_policy.c 
b/security/integrity/ima/ima_policy.c
index dbfd26b..7a63760 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -118,6 +118,7 @@ static struct ima_rule_entry default_measurement_rules[] = {
        {.action = MEASURE, .hooks.func = MODULE_CHECK, .flags = IMA_FUNC},
        {.action = MEASURE, .hooks.policy_id = FIRMWARE_CHECK,
         .flags = IMA_FUNC},
+       {.action = MEASURE, .hooks.policy_id = POLICY_CHECK, .flags = IMA_FUNC},
 };
 
 static struct ima_rule_entry default_appraise_rules[] = {
@@ -618,6 +619,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry 
*entry)
                                entry->hooks.policy_id = FIRMWARE_CHECK;
                        else if (strcmp(args[0].from, "MODULE_CHECK") == 0)
                                entry->hooks.policy_id = MODULE_CHECK;
+                       else if (strcmp(args[0].from, "POLICY_CHECK") == 0)
+                               entry->hooks.policy_id = POLICY_CHECK;
                        else
                                result = -EINVAL;
                        if (!result)
@@ -776,6 +779,8 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry 
*entry)
                temp_ima_appraise |= IMA_APPRAISE_MODULES;
        else if (entry->hooks.policy_id == FIRMWARE_CHECK)
                temp_ima_appraise |= IMA_APPRAISE_FIRMWARE;
+       else if (entry->hooks.policy_id == POLICY_CHECK)
+               temp_ima_appraise |= IMA_APPRAISE_POLICY;
        audit_log_format(ab, "res=%d", !result);
        audit_log_end(ab);
        return result;
@@ -862,7 +867,8 @@ static char *mask_tokens[] = {
 enum {
        func_file = 0, func_mmap, func_bprm,
        func_module, func_post,
-       func_kexec, func_initramfs, func_firmware
+       func_kexec, func_initramfs, func_firmware,
+       func_policy
 };
 
 static char *func_tokens[] = {
@@ -873,7 +879,8 @@ static char *func_tokens[] = {
        "POST_SETATTR",
        "KEXEC_CHECK",
        "INITRAMFS_CHECK",
-       "FIRMWARE_CHECK"
+       "FIRMWARE_CHECK",
+       "POLICY_CHECK"
 };
 
 void *ima_policy_start(struct seq_file *m, loff_t *pos)
@@ -961,6 +968,9 @@ int ima_policy_show(struct seq_file *m, void *v)
                        case MODULE_CHECK:
                                seq_printf(m, pt(Opt_func), ft(func_module));
                                break;
+                       case POLICY_CHECK:
+                               seq_printf(m, pt(Opt_func), ft(func_policy));
+                               break;
                        default:
                                snprintf(tbuf, sizeof(tbuf), "%d",
                                         entry->hooks.func);
-- 
2.1.0


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to