summaryrefslogtreecommitdiff
path: root/security/integrity/ima/ima_fs.c
diff options
context:
space:
mode:
authorPetko Manolov <petkan@mip-labs.com>2015-12-02 17:47:54 +0200
committerOleksandr Suvorov <oleksandr.suvorov@toradex.com>2020-05-25 13:57:21 +0300
commitcaf4e7107db7f3f940af9e1afa93608cd2bcb584 (patch)
tree4e14da7ce0241942dc492160859fb817efafc71d /security/integrity/ima/ima_fs.c
parent8ad906bec0b972876db52d4256b34023ec81631d (diff)
IMA: policy can now be updated multiple times
commit 38d859f991f3a05b352a06f82af0baa1acf33e02 upstream The new rules get appended to the original policy, forming a queue. The new rules are first added to a temporary list, which on error get released without disturbing the normal IMA operations. On success both lists (the current policy and the new rules) are spliced. IMA policy reads are many orders of magnitude more numerous compared to writes, the match code is RCU protected. The updater side also does list splice in RCU manner. Signed-off-by: Petko Manolov <petkan@mip-labs.com> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/integrity/ima/ima_fs.c')
-rw-r--r--security/integrity/ima/ima_fs.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 30aced99bc55..777867d42d27 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -25,6 +25,8 @@
#include "ima.h"
+static DEFINE_MUTEX(ima_write_mutex);
+
static int valid_policy = 1;
static ssize_t ima_show_htable_value(char __user *buf, size_t count,
@@ -261,6 +263,11 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
{
char *data = NULL;
ssize_t result;
+ int res;
+
+ res = mutex_lock_interruptible(&ima_write_mutex);
+ if (res)
+ return res;
if (datalen >= PAGE_SIZE)
datalen = PAGE_SIZE - 1;
@@ -286,6 +293,8 @@ out:
if (result < 0)
valid_policy = 0;
kfree(data);
+ mutex_unlock(&ima_write_mutex);
+
return result;
}
@@ -337,8 +346,12 @@ static int ima_release_policy(struct inode *inode, struct file *file)
return 0;
}
ima_update_policy();
+#ifndef CONFIG_IMA_WRITE_POLICY
securityfs_remove(ima_policy);
ima_policy = NULL;
+#else
+ clear_bit(IMA_FS_BUSY, &ima_fs_flags);
+#endif
return 0;
}