From: Krzysztof Struczynski krzysztof.struczynski@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49KW1 CVE: NA
--------------------------------
Collate global variables describing the ima policy in one structure and add it to the ima namespace. Collate setup data (parsed kernel boot parameters) in a separate structure.
Per namespace policy is not yet properly set and it is not used. This will be done in the following patches.
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 | 2 ++ security/integrity/ima/ima.h | 24 +++++++++++++++++ security/integrity/ima/ima_init.c | 3 ++- security/integrity/ima/ima_ns.c | 41 +++++++++++++++++++++++++++-- security/integrity/ima/ima_policy.c | 26 ++++++++++++++++++ 5 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/include/linux/ima.h b/include/linux/ima.h index 88734870af59..5cb5659c0a06 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -17,6 +17,7 @@ struct nsproxy; struct task_struct; struct list_head; struct llist_node; +struct ima_policy_data;
#ifdef CONFIG_IMA extern int ima_bprm_check(struct linux_binprm *bprm); @@ -218,6 +219,7 @@ struct ima_namespace { struct llist_node cleanup_list; /* namespaces on a death row */ atomic_t inactive; /* set only when ns is added to the cleanup list */ bool frozen; + struct ima_policy_data *policy_data; } __randomize_layout;
extern struct ima_namespace init_ima_ns; diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index da7e732b7e80..6a59c8b9bc4c 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -63,6 +63,14 @@ extern size_t ima_digest_db_max_size __ro_after_init; extern size_t ima_digest_db_size; #endif
+/* IMA policy setup data */ +struct ima_policy_setup_data { + int ima_policy; + int ima_appraise; + bool ima_use_secure_boot; + bool ima_use_appraise_tcb; +}; + /* IMA event related data */ struct ima_event_data { struct integrity_iint_cache *iint; @@ -291,6 +299,8 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, struct ima_template_desc **template_desc, const char *keyring); void ima_init_policy(void); +void ima_init_ns_policy(struct ima_namespace *ima_ns, + const struct ima_policy_setup_data *policy_setup_data); void ima_update_policy(void); void ima_update_policy_flag(void); ssize_t ima_parse_add_rule(char *); @@ -363,6 +373,20 @@ static inline enum integrity_status ima_get_cache_status(struct integrity_iint_c
#endif /* CONFIG_IMA_APPRAISE */
+struct ima_policy_data { + struct list_head ima_default_rules; + struct list_head ima_policy_rules; + struct list_head ima_temp_rules; + struct list_head *ima_rules; + bool ima_fail_unverifiable_sigs; + int ima_policy_flag; /* current content of the policy */ + int ima_appraise; + int temp_ima_appraise; +}; + +extern struct ima_policy_data init_policy_data; +extern struct ima_policy_setup_data init_policy_setup_data; + extern struct list_head ima_ns_list; extern struct rw_semaphore ima_ns_list_lock;
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 2238fb21eaf0..9f0e9dc3b77f 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -32,7 +32,8 @@ struct ima_namespace init_ima_ns = { #ifdef CONFIG_IMA_NS .ns.ops = &imans_operations, #endif - .frozen = true + .frozen = true, + .policy_data = &init_policy_data, }; EXPORT_SYMBOL(init_ima_ns);
diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c index 3a98cd536d05..1aeb9cfeb3a2 100644 --- a/security/integrity/ima/ima_ns.c +++ b/security/integrity/ima/ima_ns.c @@ -51,9 +51,38 @@ static struct ima_namespace *ima_ns_alloc(void)
ima_ns = kzalloc(sizeof(*ima_ns), GFP_KERNEL); if (!ima_ns) - return NULL; + goto out; + + ima_ns->policy_data = kzalloc(sizeof(struct ima_policy_data), + GFP_KERNEL); + if (!ima_ns->policy_data) + goto out_free;
return ima_ns; + +out_free: + kfree(ima_ns); +out: + return NULL; +} + +static void ima_set_ns_policy(struct ima_namespace *ima_ns, + char *policy_setup_str) +{ + struct ima_policy_setup_data setup_data; + +#ifdef CONFIG_IMA_APPRAISE + setup_data.ima_appraise = IMA_APPRAISE_ENFORCE; +#endif + /* Configuring IMA namespace will be implemented in the following + * patches. When it is done, parse configuration string and store result + * in setup_data. Temporarily use init_policy_setup_data. + */ + setup_data = init_policy_setup_data; + ima_ns->policy_data->ima_fail_unverifiable_sigs = + init_ima_ns.policy_data->ima_fail_unverifiable_sigs; + + ima_init_ns_policy(ima_ns, &setup_data); }
/** @@ -64,7 +93,7 @@ static struct ima_namespace *ima_ns_alloc(void) * Return: ERR_PTR(-ENOMEM) on error (failure to kmalloc), new ns otherwise */ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns, - struct ima_namespace *old_ns) + struct ima_namespace *old_ns) { struct ima_namespace *ns; struct ucounts *ucounts; @@ -91,9 +120,14 @@ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns, ns->ucounts = ucounts; ns->frozen = false;
+ INIT_LIST_HEAD(&ns->policy_data->ima_default_rules); + INIT_LIST_HEAD(&ns->policy_data->ima_policy_rules); + INIT_LIST_HEAD(&ns->policy_data->ima_temp_rules); + return ns;
fail_free: + kfree(ns->policy_data); kfree(ns); fail_dec: dec_ima_namespaces(ucounts); @@ -139,6 +173,7 @@ static void destroy_ima_ns(struct ima_namespace *ns) dec_ima_namespaces(ns->ucounts); put_user_ns(ns->user_ns); ns_free_inum(&ns->ns); + kfree(ns->policy_data); kfree(ns); }
@@ -238,6 +273,8 @@ static int imans_activate(struct ima_namespace *ima_ns) if (ima_ns->frozen) goto out;
+ ima_set_ns_policy(ima_ns, NULL); + ima_ns->frozen = true;
down_write(&ima_ns_list_lock); diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 8e288da66503..bdfe5ec0a79a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -235,6 +235,17 @@ static struct list_head *ima_rules = &ima_default_rules;
static int ima_policy __initdata;
+struct ima_policy_setup_data init_policy_setup_data = { +#ifdef CONFIG_IMA_APPRAISE + .ima_appraise = IMA_APPRAISE_ENFORCE, +#endif +}; +struct ima_policy_data init_policy_data = { + .ima_default_rules = LIST_HEAD_INIT(init_policy_data.ima_default_rules), + .ima_policy_rules = LIST_HEAD_INIT(init_policy_data.ima_policy_rules), + .ima_temp_rules = LIST_HEAD_INIT(init_policy_data.ima_temp_rules), +}; + static int __init default_measure_policy_setup(char *str) { if (ima_policy) @@ -839,6 +850,21 @@ static int __init ima_init_arch_policy(void) return i; }
+/** + * ima_init_ns_policy - initialize the default measure rules. + * @ima_ns: pointer to the namespace whose rules are being initialized + * @setup_data: pointer to the policy setup data + */ +void ima_init_ns_policy(struct ima_namespace *ima_ns, + const struct ima_policy_setup_data *setup_data) +{ + /* Set policy rules to the empty set of default rules. The rest will be + * implemented after namespacing policy. + */ + ima_ns->policy_data->ima_rules = + &ima_ns->policy_data->ima_default_rules; +} + /** * ima_init_policy - initialize the default measure rules. *