diff --git a/include/linux/ima.h b/include/linux/ima.h index 88734870af59a51437b2599a6fe94c1a7d2f7e6d..5cb5659c0a06d568ae5f40d660af81a035a2c624 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 da7e732b7e800fb65ccd65ef7ef6f8e9fa9c8c79..6a59c8b9bc4c0c791cf83fb8e8552e7893833241 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 2238fb21eaf09c5378997d6bdbe862033dce7eb1..9f0e9dc3b77fed702695c909421ab665b7d18b4a 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 3a98cd536d05a4dfb4849f767aa128fdae14b908..1aeb9cfeb3a2c3aa371b3699f528d25948ddd1b4 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 8e288da665034a4f5a1826a4851cc9f1c1dbe33a..bdfe5ec0a79a86147afafb4cb75fc9f4556724b1 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. *