From: Krzysztof Struczynski <krzysztof.struczynski@xxxxxxxxxx> Parse per ima namespace policy file if the file path is set. Signed-off-by: Krzysztof Struczynski <krzysztof.struczynski@xxxxxxxxxx> --- security/integrity/ima/ima.h | 7 ++++--- security/integrity/ima/ima_fs.c | 17 +++++++++++------ security/integrity/ima/ima_ns.c | 18 ++++++++++++++++-- security/integrity/ima/ima_policy.c | 25 +++++++++++-------------- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 48d09efaffbe..b55d25c2bf63 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -309,10 +309,10 @@ int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, 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(struct ima_namespace *ima_ns); void ima_update_policy_flag(struct ima_namespace *ima_ns); -ssize_t ima_parse_add_rule(char *); -void ima_delete_rules(void); +ssize_t ima_parse_add_rule(char *rule, struct ima_namespace *ima_ns); +void ima_delete_rules(struct ima_namespace *ima_ns); int ima_check_policy(const struct ima_namespace *ima_ns); void *ima_policy_start(struct seq_file *m, loff_t *pos); void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos); @@ -439,6 +439,7 @@ static inline struct ima_namespace *get_current_ns(void) void ima_delete_ns_rules(struct ima_policy_data *policy_data, bool is_root_ns); +ssize_t ima_read_ns_policy(char *path, struct ima_namespace *ima_ns); ssize_t ima_ns_write_policy_for_children(struct ima_namespace *ima_ns, char *policy_path); diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 6c033857f521..7b93c338a478 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -343,7 +343,7 @@ static const struct file_operations ima_ascii_measurements_ops = { .release = seq_release, }; -static ssize_t ima_read_policy(char *path) +static ssize_t ima_read_policy(char *path, struct ima_namespace *ima_ns) { void *data; char *datap; @@ -365,7 +365,7 @@ static ssize_t ima_read_policy(char *path) datap = data; while (size > 0 && (p = strsep(&datap, "\n"))) { pr_debug("rule: %s\n", p); - rc = ima_parse_add_rule(p); + rc = ima_parse_add_rule(p, ima_ns); if (rc < 0) break; size -= rc; @@ -406,7 +406,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, goto out_free; if (data[0] == '/') { - result = ima_read_policy(data); + result = ima_read_policy(data, ima_ns); } else if (ima_ns->policy_data->ima_appraise & IMA_APPRAISE_POLICY) { pr_err("signed policy file (specified as an absolute pathname) required\n"); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, @@ -414,7 +414,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, 1, 0); result = -EACCES; } else { - result = ima_parse_add_rule(data); + result = ima_parse_add_rule(data, ima_ns); } mutex_unlock(&ima_write_mutex); out_free: @@ -502,13 +502,13 @@ static int ima_release_policy(struct inode *inode, struct file *file) "policy_update", cause, !valid_policy, 0); if (!valid_policy) { - ima_delete_rules(); + ima_delete_rules(ima_ns); valid_policy = 1; clear_bit(IMA_FS_BUSY, &ima_fs_flags); return 0; } - ima_update_policy(); + ima_update_policy(ima_ns); #if !defined(CONFIG_IMA_WRITE_POLICY) && !defined(CONFIG_IMA_READ_POLICY) securityfs_remove(ima_policy); ima_policy = NULL; @@ -629,6 +629,11 @@ static const struct file_operations ima_kcmd_for_children_ops = { .open = ima_open_for_children, .write = ima_write_kcmd_for_children, }; + +ssize_t ima_read_ns_policy(char *path, struct ima_namespace *ima_ns) +{ + return ima_read_policy(path, ima_ns); +} #endif /* CONFIG_IMA_NS */ int __init ima_fs_init(void) diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c index dd0328ee715f..ec3abc803c82 100644 --- a/security/integrity/ima/ima_ns.c +++ b/security/integrity/ima/ima_ns.c @@ -91,10 +91,24 @@ static int ima_set_ns_policy(struct ima_namespace *ima_ns) setup_data.ima_appraise = IMA_APPRAISE_ENFORCE; #endif ima_init_ns_policy(ima_ns, &setup_data); - return result; + } else { + ima_init_ns_policy(ima_ns, ima_ns->policy_setup_for_children); } - ima_init_ns_policy(ima_ns, ima_ns->policy_setup_for_children); + if (ima_ns->policy_path_for_children) { + result = ima_read_ns_policy(ima_ns->policy_path_for_children, + ima_ns); + if ((result >= 0) && !ima_check_policy(ima_ns)) { + integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, + "policy_update", "completed", 0, 0); + ima_update_policy(ima_ns); + } else { + ima_delete_rules(ima_ns); + ima_delete_ns_rules(ima_ns->policy_data, false); + integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, + "policy_update", "failed", 1, 0); + } + } return result; } diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 3d712c062ed0..d4774eab6a98 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -735,7 +735,8 @@ static void add_rules(struct ima_namespace *ima_ns, } } -static int ima_parse_rule(char *rule, struct ima_rule_entry *entry); +static int ima_parse_rule(char *rule, struct ima_rule_entry *entry, + struct ima_namespace *ima_ns); static int __init ima_init_arch_policy(void) { @@ -765,7 +766,8 @@ static int __init ima_init_arch_policy(void) result = strlcpy(rule, *rules, sizeof(rule)); INIT_LIST_HEAD(&arch_policy_entry[i].list); - result = ima_parse_rule(rule, &arch_policy_entry[i]); + result = ima_parse_rule(rule, &arch_policy_entry[i], + &init_ima_ns); if (result) { pr_warn("Skipping unknown architecture policy rule: %s\n", rule); @@ -895,10 +897,8 @@ int ima_check_policy(const struct ima_namespace *ima_ns) * Policy rules are never deleted so ima_policy_flag gets zeroed only once when * we switch from the default policy to user defined. */ -void ima_update_policy(void) +void ima_update_policy(struct ima_namespace *ima_ns) { - /* Update only the current ima namespace */ - struct ima_namespace *ima_ns = get_current_ns(); struct list_head *policy = &ima_ns->policy_data->ima_policy_rules; list_splice_tail_init_rcu(&ima_ns->policy_data->ima_temp_rules, @@ -1151,7 +1151,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry) return true; } -static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) +static int ima_parse_rule(char *rule, struct ima_rule_entry *entry, + struct ima_namespace *ima_ns) { struct audit_buffer *ab; char *from; @@ -1160,7 +1161,6 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) struct ima_template_desc *template_desc; int result = 0; size_t keyrings_len; - struct ima_namespace *ima_ns = get_current_ns(); ab = integrity_audit_log_start(audit_context(), GFP_KERNEL, AUDIT_INTEGRITY_POLICY_RULE); @@ -1547,19 +1547,18 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) /** * ima_parse_add_rule - add a rule to ima_policy_rules * @rule - ima measurement policy rule + * @ima_ns - pointer to the ima namespace the rule will be added to * * Avoid locking by allowing just one writer at a time in ima_write_policy() * Returns the length of the rule parsed, an error code on failure */ -ssize_t ima_parse_add_rule(char *rule) +ssize_t ima_parse_add_rule(char *rule, struct ima_namespace *ima_ns) { static const char op[] = "update_policy"; char *p; struct ima_rule_entry *entry; ssize_t result, len; int audit_info = 0; - /* Add rules only to the current ima namespace */ - struct ima_namespace *ima_ns = get_current_ns(); p = strsep(&rule, "\n"); len = strlen(p) + 1; @@ -1577,7 +1576,7 @@ ssize_t ima_parse_add_rule(char *rule) INIT_LIST_HEAD(&entry->list); - result = ima_parse_rule(p, entry); + result = ima_parse_rule(p, entry, ima_ns); if (result) { ima_free_rule(entry); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, @@ -1597,10 +1596,8 @@ ssize_t ima_parse_add_rule(char *rule) * different from the active one. There is also only one user of * ima_delete_rules() at a time. */ -void ima_delete_rules(void) +void ima_delete_rules(struct ima_namespace *ima_ns) { - /* Delete rules only from the current ima namespace */ - struct ima_namespace *ima_ns = get_current_ns(); struct ima_rule_entry *entry, *tmp; ima_ns->policy_data->temp_ima_appraise = 0; -- 2.20.1 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/containers