diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 16d85273d40865f8550312b912149ea8224384bb..973b5683a92ef6a487632701f6ee3ddf5b85a7b4 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -288,7 +288,12 @@ static struct dentry *runtime_measurements_count; static struct dentry *violations; static struct dentry *ima_policy; -static atomic_t policy_opencount = ATOMIC_INIT(1); +enum ima_fs_flags { + IMA_FS_BUSY, +}; + +static unsigned long ima_fs_flags; + /* * ima_open_policy: sequentialize access to the policy file */ @@ -297,9 +302,9 @@ static int ima_open_policy(struct inode *inode, struct file *filp) /* No point in being allowed to open it if you aren't going to write */ if (!(filp->f_flags & O_WRONLY)) return -EACCES; - if (atomic_dec_and_test(&policy_opencount)) - return 0; - return -EBUSY; + if (test_and_set_bit(IMA_FS_BUSY, &ima_fs_flags)) + return -EBUSY; + return 0; } /* @@ -311,12 +316,16 @@ static int ima_open_policy(struct inode *inode, struct file *filp) */ static int ima_release_policy(struct inode *inode, struct file *file) { - pr_info("IMA: policy update %s\n", - valid_policy ? "completed" : "failed"); + const char *cause = valid_policy ? "completed" : "failed"; + + pr_info("IMA: policy update %s\n", cause); + integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, + "policy_update", cause, !valid_policy, 0); + if (!valid_policy) { ima_delete_rules(); valid_policy = 1; - atomic_set(&policy_opencount, 1); + clear_bit(IMA_FS_BUSY, &ima_fs_flags); return 0; } ima_update_policy(); diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d2c47d4df7b7339d017fb0459c023569ca1a6a56..0d14d25918051c5e8119e4a357639c5822b67f03 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -356,19 +356,8 @@ void __init ima_init_policy(void) */ void ima_update_policy(void) { - static const char op[] = "policy_update"; - const char *cause = "already-exists"; - int result = 1; - int audit_info = 0; - - if (ima_rules == &ima_default_rules) { - ima_rules = &ima_policy_rules; - ima_update_policy_flag(); - cause = "complete"; - result = 0; - } - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, cause, result, audit_info); + ima_rules = &ima_policy_rules; + ima_update_policy_flag(); } enum { @@ -686,14 +675,6 @@ ssize_t ima_parse_add_rule(char *rule) ssize_t result, len; int audit_info = 0; - /* Prevent installed policy from changing */ - if (ima_rules != &ima_default_rules) { - integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, "already-exists", - -EACCES, audit_info); - return -EACCES; - } - p = strsep(&rule, "\n"); len = strlen(p) + 1; p += strspn(p, " \t");