ima: measure and appraise the IMA policy itself
Add support for measuring and appraising the IMA policy itself. Changelog v4: - use braces on both if/else branches, even if single line on one of the branches - Dmitry - Use the id mapping - Dmitry Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Acked-by: Petko Manolov <petkan@mip-labs.com> Acked-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com>
This commit is contained in:
parent
7429b09281
commit
19f8a84713
4 changed files with 24 additions and 3 deletions
|
@ -149,6 +149,7 @@ enum ima_hooks {
|
|||
FIRMWARE_CHECK,
|
||||
KEXEC_KERNEL_CHECK,
|
||||
KEXEC_INITRAMFS_CHECK,
|
||||
POLICY_CHECK,
|
||||
MAX_CHECK
|
||||
};
|
||||
|
||||
|
@ -191,6 +192,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(enum ima_hooks func,
|
||||
|
|
|
@ -325,10 +325,18 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
|
|||
if (result < 0)
|
||||
goto out_free;
|
||||
|
||||
if (data[0] == '/')
|
||||
if (data[0] == '/') {
|
||||
result = ima_read_policy(data);
|
||||
else
|
||||
} else if (ima_appraise & IMA_APPRAISE_POLICY) {
|
||||
pr_err("IMA: signed policy file (specified as an absolute pathname) 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:
|
||||
kfree(data);
|
||||
|
|
|
@ -344,6 +344,7 @@ static int read_idmap[READING_MAX_ID] = {
|
|||
[READING_MODULE] = MODULE_CHECK,
|
||||
[READING_KEXEC_IMAGE] = KEXEC_KERNEL_CHECK,
|
||||
[READING_KEXEC_INITRAMFS] = KEXEC_INITRAMFS_CHECK,
|
||||
[READING_POLICY] = POLICY_CHECK
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -114,6 +114,7 @@ static struct ima_rule_entry default_measurement_rules[] = {
|
|||
.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID},
|
||||
{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
|
||||
{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
|
||||
{.action = MEASURE, .func = 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)
|
|||
else if (strcmp(args[0].from, "KEXEC_INITRAMFS_CHECK")
|
||||
== 0)
|
||||
entry->func = KEXEC_INITRAMFS_CHECK;
|
||||
else if (strcmp(args[0].from, "POLICY_CHECK") == 0)
|
||||
entry->func = 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->func == FIRMWARE_CHECK)
|
||||
temp_ima_appraise |= IMA_APPRAISE_FIRMWARE;
|
||||
else if (entry->func == 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_firmware, func_post,
|
||||
func_kexec_kernel, func_kexec_initramfs
|
||||
func_kexec_kernel, func_kexec_initramfs,
|
||||
func_policy
|
||||
};
|
||||
|
||||
static char *func_tokens[] = {
|
||||
|
@ -873,6 +879,7 @@ static char *func_tokens[] = {
|
|||
"FIRMWARE_CHECK",
|
||||
"KEXEC_KERNEL_CHECK",
|
||||
"KEXEC_INITRAMFS_CHECK",
|
||||
"POLICY_CHECK",
|
||||
"POST_SETATTR"
|
||||
};
|
||||
|
||||
|
@ -944,6 +951,9 @@ static void policy_func_show(struct seq_file *m, enum ima_hooks func)
|
|||
case KEXEC_INITRAMFS_CHECK:
|
||||
seq_printf(m, pt(Opt_func), ft(func_kexec_initramfs));
|
||||
break;
|
||||
case POLICY_CHECK:
|
||||
seq_printf(m, pt(Opt_func), ft(func_policy));
|
||||
break;
|
||||
default:
|
||||
snprintf(tbuf, sizeof(tbuf), "%d", func);
|
||||
seq_printf(m, pt(Opt_func), tbuf);
|
||||
|
|
Loading…
Reference in a new issue