From: Krzysztof Struczynski krzysztof.struczynski@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49KW1 CVE: NA
--------------------------------
Set ML template based on the ima_template string. It can be defined by the user through kcmd_for_children ima securityfs entry. Acceptable values are the same as for the ima_template kernel boot parameter.
Signed-off-by: Krzysztof Struczynski krzysztof.struczynski@huawei.com Reviewed-by: Zhang Tianxing zhangtianxing3@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/linux/ima.h | 1 + security/integrity/ima/ima.h | 2 ++ security/integrity/ima/ima_init.c | 1 + security/integrity/ima/ima_ns.c | 30 ++++++++++++++++++++- security/integrity/ima/ima_policy.c | 2 +- security/integrity/ima/ima_template.c | 38 ++++++++++++++++++--------- 6 files changed, 59 insertions(+), 15 deletions(-)
diff --git a/include/linux/ima.h b/include/linux/ima.h index f011c6e6aa86..5a2dbd8fab6d 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -240,6 +240,7 @@ struct ima_namespace { #ifdef CONFIG_KEYS struct key_tag *key_domain; #endif + struct ima_template_desc *ima_template; struct task_struct *activating_tsk; /* used only for the ns activation */ } __randomize_layout;
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index aff8a3c748bf..acdc8ee6e53d 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -172,8 +172,10 @@ int template_desc_init_fields(const char *template_fmt, const struct ima_template_field ***fields, int *num_fields); struct ima_template_desc *ima_template_desc_current(void); +struct ima_template_desc *ima_template_desc_ns(struct ima_namespace *ima_ns); struct ima_template_desc *lookup_template_desc(const char *name); bool ima_template_has_modsig(const struct ima_template_desc *ima_template); +int ima_template_setup(char *str, struct ima_namespace *ima_ns); int ima_restore_measurement_entry(struct ima_template_entry *entry); int ima_restore_measurement_list(loff_t bufsize, void *buf); int ima_measurements_show(struct seq_file *m, void *v); diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 73fb0f0e82c5..f4bd3ca98b54 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -48,6 +48,7 @@ struct ima_namespace init_ima_ns = { #ifdef CONFIG_KEYS .key_domain = &init_ima_key_domain, #endif + .ima_template = NULL, }; EXPORT_SYMBOL(init_ima_ns);
diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c index 29a1cbdac40d..97185b8ed52c 100644 --- a/security/integrity/ima/ima_ns.c +++ b/security/integrity/ima/ima_ns.c @@ -49,6 +49,28 @@ static void dec_ima_namespaces(struct ucounts *ucounts) return dec_ucount(ucounts, UCOUNT_IMA_NAMESPACES); }
+static int ima_set_ns_template(struct ima_namespace *ima_ns) +{ + int result; + + if (!ima_ns->ima_template) + ima_ns->ima_template = + lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE); + + result = template_desc_init_fields(ima_ns->ima_template->fmt, + &(ima_ns->ima_template->fields), + &(ima_ns->ima_template->num_fields)); + if (result < 0) { + pr_err("template %s init failed, result: %d\n", + (strlen(ima_ns->ima_template->name) ? + ima_ns->ima_template->name : + ima_ns->ima_template->fmt), result); + ima_ns->ima_template = NULL; + } + + return result; +} + static int ima_ns_add_boot_aggregate(struct ima_namespace *ima_ns) { static const char op[] = "ns_add_boot_aggregate"; @@ -245,6 +267,7 @@ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns, #endif ns->x509_path_for_children = NULL; ns->policy_setup_for_children = NULL; + ns->ima_template = NULL;
INIT_LIST_HEAD(&ns->ns_measurements); INIT_LIST_HEAD(&ns->policy_data->ima_default_rules); @@ -437,6 +460,10 @@ static int imans_activate(struct ima_namespace *ima_ns) if (ima_ns->frozen) goto out;
+ res = ima_set_ns_template(ima_ns); + if (res < 0) + goto out; + ima_set_ns_policy(ima_ns);
ima_ns->frozen = true; @@ -556,10 +583,11 @@ struct ima_kernel_param { int (*set)(char *val, struct ima_namespace *ima_ns); };
-/* TODO: add ima_template, ima_template_fmt, ima_hash, ... */ +/* TODO: add ima_template_fmt, ima_hash, ... */ static const struct ima_kernel_param ima_kernel_params[] = { {"ima_appraise", ima_default_appraise_setup}, {"ima_policy", ima_policy_setup}, + {"ima_template", ima_template_setup}, }; static const size_t ima_kernel_params_size = ARRAY_SIZE(ima_kernel_params);
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 42bafb520e4e..35ec2c8f2069 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -737,7 +737,7 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, bool fail_unverifiable_sigs;
if (template_desc) - *template_desc = ima_template_desc_current(); + *template_desc = ima_template_desc_ns(ima_ns);
rcu_read_lock(); list_for_each_entry_rcu(entry, ima_ns->policy_data->ima_rules, list) { diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 3d6f6e9d530c..e72497f37bb5 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -59,8 +59,6 @@ static const struct ima_template_field supported_fields[] = { */ #define MAX_TEMPLATE_NAME_LEN sizeof("d-ng|n-ng|sig|buf|d-modisg|modsig|ns")
-static struct ima_template_desc *ima_template; - /** * ima_template_has_modsig - Check whether template has modsig-related fields. * @ima_template: IMA template to check. @@ -80,12 +78,12 @@ bool ima_template_has_modsig(const struct ima_template_desc *ima_template) return false; }
-static int __init ima_template_setup(char *str) +int ima_template_setup(char *str, struct ima_namespace *ima_ns) { struct ima_template_desc *template_desc; int template_len = strlen(str);
- if (ima_template) + if (ima_ns->ima_template) return 1;
ima_init_template_list(); @@ -111,16 +109,21 @@ static int __init ima_template_setup(char *str) return 1; }
- ima_template = template_desc; + ima_ns->ima_template = template_desc; return 1; } -__setup("ima_template=", ima_template_setup); + +static int __init template_setup(char *str) +{ + return ima_template_setup(str, &init_ima_ns); +} +__setup("ima_template=", template_setup);
static int __init ima_template_fmt_setup(char *str) { int num_templates = ARRAY_SIZE(builtin_templates);
- if (ima_template) + if (init_ima_ns.ima_template) return 1;
if (template_desc_init_fields(str, NULL, NULL) < 0) { @@ -130,7 +133,7 @@ static int __init ima_template_fmt_setup(char *str) }
builtin_templates[num_templates - 1].fmt = str; - ima_template = builtin_templates + num_templates - 1; + init_ima_ns.ima_template = builtin_templates + num_templates - 1;
return 1; } @@ -247,14 +250,23 @@ void ima_init_template_list(void) spin_unlock(&template_list); }
-struct ima_template_desc *ima_template_desc_current(void) +struct ima_template_desc *ima_template_desc_ns(struct ima_namespace *ima_ns) { - if (!ima_template) { + if (!ima_ns) + return NULL; + + if (!ima_ns->ima_template) { ima_init_template_list(); - ima_template = - lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE); + ima_ns->ima_template = + lookup_template_desc(CONFIG_IMA_DEFAULT_TEMPLATE); } - return ima_template; + return ima_ns->ima_template; +} + +struct ima_template_desc *ima_template_desc_current(void) +{ + struct ima_namespace *ima_ns = get_current_ns(); + return ima_template_desc_ns(ima_ns); }
int __init ima_init_template(void)