Ver código fonte

ima: update builtin policies

This patch defines a builtin measurement policy "tcb", similar to the
existing "ima_tcb", but with additional rules to also measure files
based on the effective uid and to measure files opened with the "read"
mode bit set (eg. read, read-write).

Changing the builtin "ima_tcb" policy could potentially break existing
users.  Instead of defining a new separate boot command line option each
time the builtin measurement policy is modified, this patch defines a
single generic boot command line option "ima_policy=" to specify the
builtin policy and deprecates the use of the builtin ima_tcb policy.

[The "ima_policy=" boot command line option is based on Roberto Sassu's
"ima: added new policy type exec" patch.]

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Dr. Greg Wettstein <gw@idfusion.org>
Cc: stable@vger.kernel.org
Mimi Zohar 10 anos atrás
pai
commit
24fd03c876

+ 9 - 1
Documentation/kernel-parameters.txt

@@ -1398,7 +1398,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			The list of supported hash algorithms is defined
 			The list of supported hash algorithms is defined
 			in crypto/hash_info.h.
 			in crypto/hash_info.h.
 
 
-	ima_tcb		[IMA]
+	ima_policy=	[IMA]
+			The builtin measurement policy to load during IMA
+			setup.  Specyfing "tcb" as the value, measures all
+			programs exec'd, files mmap'd for exec, and all files
+			opened with the read mode bit set by either the
+			effective uid (euid=0) or uid=0.
+			Format: "tcb"
+
+	ima_tcb		[IMA] Deprecated.  Use ima_policy= instead.
 			Load a policy which meets the needs of the Trusted
 			Load a policy which meets the needs of the Trusted
 			Computing Base.  This means IMA will measure all
 			Computing Base.  This means IMA will measure all
 			programs exec'd, files mmap'd for exec, and all files
 			programs exec'd, files mmap'd for exec, and all files

+ 56 - 9
security/integrity/ima/ima_policy.c

@@ -44,6 +44,8 @@ enum lsm_rule_types { LSM_OBJ_USER, LSM_OBJ_ROLE, LSM_OBJ_TYPE,
 	LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
 	LSM_SUBJ_USER, LSM_SUBJ_ROLE, LSM_SUBJ_TYPE
 };
 };
 
 
+enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB };
+
 struct ima_rule_entry {
 struct ima_rule_entry {
 	struct list_head list;
 	struct list_head list;
 	int action;
 	int action;
@@ -72,7 +74,7 @@ struct ima_rule_entry {
  * normal users can easily run the machine out of memory simply building
  * normal users can easily run the machine out of memory simply building
  * and running executables.
  * and running executables.
  */
  */
-static struct ima_rule_entry default_rules[] = {
+static struct ima_rule_entry dont_measure_rules[] = {
 	{.action = DONT_MEASURE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE, .fsmagic = PROC_SUPER_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE, .fsmagic = SYSFS_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE, .fsmagic = DEBUGFS_MAGIC, .flags = IMA_FSMAGIC},
@@ -83,13 +85,29 @@ static struct ima_rule_entry default_rules[] = {
 	{.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC},
 	{.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC,
 	{.action = DONT_MEASURE, .fsmagic = CGROUP_SUPER_MAGIC,
 	 .flags = IMA_FSMAGIC},
 	 .flags = IMA_FSMAGIC},
-	{.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC},
+	{.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}
+};
+
+static struct ima_rule_entry original_measurement_rules[] = {
+	{.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC,
+	 .flags = IMA_FUNC | IMA_MASK},
+	{.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC,
+	 .flags = IMA_FUNC | IMA_MASK},
+	{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
+	 .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_MASK | IMA_UID},
+	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
+	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
+};
+
+static struct ima_rule_entry default_measurement_rules[] = {
 	{.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC,
 	{.action = MEASURE, .func = MMAP_CHECK, .mask = MAY_EXEC,
 	 .flags = IMA_FUNC | IMA_MASK},
 	 .flags = IMA_FUNC | IMA_MASK},
 	{.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC,
 	{.action = MEASURE, .func = BPRM_CHECK, .mask = MAY_EXEC,
 	 .flags = IMA_FUNC | IMA_MASK},
 	 .flags = IMA_FUNC | IMA_MASK},
-	{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ, .uid = GLOBAL_ROOT_UID,
-	 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
+	{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
+	 .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_EUID},
+	{.action = MEASURE, .func = FILE_CHECK, .mask = MAY_READ,
+	 .uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_INMASK | IMA_UID},
 	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = MODULE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
 	{.action = MEASURE, .func = FIRMWARE_CHECK, .flags = IMA_FUNC},
 };
 };
@@ -121,14 +139,29 @@ static struct list_head *ima_rules;
 
 
 static DEFINE_MUTEX(ima_rules_mutex);
 static DEFINE_MUTEX(ima_rules_mutex);
 
 
-static bool ima_use_tcb __initdata;
+static int ima_policy __initdata;
 static int __init default_measure_policy_setup(char *str)
 static int __init default_measure_policy_setup(char *str)
 {
 {
-	ima_use_tcb = 1;
+	if (ima_policy)
+		return 1;
+
+	ima_policy = ORIGINAL_TCB;
 	return 1;
 	return 1;
 }
 }
 __setup("ima_tcb", default_measure_policy_setup);
 __setup("ima_tcb", default_measure_policy_setup);
 
 
+static int __init policy_setup(char *str)
+{
+	if (ima_policy)
+		return 1;
+
+	if (strcmp(str, "tcb") == 0)
+		ima_policy = DEFAULT_TCB;
+
+	return 1;
+}
+__setup("ima_policy=", policy_setup);
+
 static bool ima_use_appraise_tcb __initdata;
 static bool ima_use_appraise_tcb __initdata;
 static int __init default_appraise_policy_setup(char *str)
 static int __init default_appraise_policy_setup(char *str)
 {
 {
@@ -352,13 +385,27 @@ void __init ima_init_policy(void)
 {
 {
 	int i, measure_entries, appraise_entries;
 	int i, measure_entries, appraise_entries;
 
 
-	/* if !ima_use_tcb set entries = 0 so we load NO default rules */
-	measure_entries = ima_use_tcb ? ARRAY_SIZE(default_rules) : 0;
+	/* if !ima_policy set entries = 0 so we load NO default rules */
+	measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0;
 	appraise_entries = ima_use_appraise_tcb ?
 	appraise_entries = ima_use_appraise_tcb ?
 			 ARRAY_SIZE(default_appraise_rules) : 0;
 			 ARRAY_SIZE(default_appraise_rules) : 0;
 
 
 	for (i = 0; i < measure_entries; i++)
 	for (i = 0; i < measure_entries; i++)
-		list_add_tail(&default_rules[i].list, &ima_default_rules);
+		list_add_tail(&dont_measure_rules[i].list, &ima_default_rules);
+
+	switch (ima_policy) {
+	case ORIGINAL_TCB:
+		for (i = 0; i < ARRAY_SIZE(original_measurement_rules); i++)
+			list_add_tail(&original_measurement_rules[i].list,
+				      &ima_default_rules);
+		break;
+	case DEFAULT_TCB:
+		for (i = 0; i < ARRAY_SIZE(default_measurement_rules); i++)
+			list_add_tail(&default_measurement_rules[i].list,
+				      &ima_default_rules);
+	default:
+		break;
+	}
 
 
 	for (i = 0; i < appraise_entries; i++) {
 	for (i = 0; i < appraise_entries; i++) {
 		list_add_tail(&default_appraise_rules[i].list,
 		list_add_tail(&default_appraise_rules[i].list,