Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19f8a847 authored by Mimi Zohar's avatar Mimi Zohar
Browse files

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: default avatarMimi Zohar <zohar@linux.vnet.ibm.com>
Acked-by: default avatarPetko Manolov <petkan@mip-labs.com>
Acked-by: default avatarDmitry Kasatkin <dmitry.kasatkin@huawei.com>
parent 7429b092
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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,
+10 −2
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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
};

/**
+11 −1
Original line number Diff line number Diff line
@@ -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);