From 0112721df4edbdd07b800813300d76811572f080 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 22 Dec 2015 08:51:23 -0500 Subject: IMA: policy can be updated zero times Commit "IMA: policy can now be updated multiple times" assumed that the policy would be updated at least once. If there are zero updates, the temporary list head object will get added to the policy list, and later dereferenced as an IMA policy object, which means that invalid memory will be accessed. Changelog: - Move list_empty() test to ima_release_policy(), before audit msg - Mimi Signed-off-by: Sasha Levin Signed-off-by: Mimi Zohar diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 917407f..585af61 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -166,6 +166,7 @@ void ima_update_policy(void); void ima_update_policy_flag(void); ssize_t ima_parse_add_rule(char *); void ima_delete_rules(void); +int ima_check_policy(void); void *ima_policy_start(struct seq_file *m, loff_t *pos); void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos); void ima_policy_stop(struct seq_file *m, void *v); diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index eebb985..3caed6d 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -355,6 +355,11 @@ static int ima_release_policy(struct inode *inode, struct file *file) if ((file->f_flags & O_ACCMODE) == O_RDONLY) return 0; + if (valid_policy && ima_check_policy() < 0) { + cause = "failed"; + valid_policy = 0; + } + pr_info("IMA: policy update %s\n", cause); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, "policy_update", cause, !valid_policy, 0); diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index ba5d2fc..0a3b781 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -416,6 +416,14 @@ void __init ima_init_policy(void) ima_rules = &ima_default_rules; } +/* Make sure we have a valid policy, at least containing some rules. */ +int ima_check_policy() +{ + if (list_empty(&ima_temp_rules)) + return -EINVAL; + return 0; +} + /** * ima_update_policy - update default_rules with new measure rules * -- cgit v0.10.2