summaryrefslogtreecommitdiffstats
path: root/security/integrity/ima/ima_fs.c
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-04-20 10:20:54 -0400
committerJames Morris <jmorris@namei.org>2010-04-21 09:58:13 +1000
commit6ccd045630054c99ba1bb35673db12cfcf1eea58 (patch)
treebce41e39722ae178807abe2213fd94e582842bae /security/integrity/ima/ima_fs.c
parenta200005038955057063fc8ea82129ebc785df41c (diff)
ima: handle multiple rules per write
Currently IMA will only accept one rule per write(). This patch allows IMA to accept writes which contain multiple rules but only processes one rule per write. \n is used as the delimiter between rules. IMA will return a short write indicating that it only accepted up to the first \n. This allows simple userspace utilities like cat to be used to load an IMA policy instead of needing a special userspace utility that understood 'one write per rule' Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/integrity/ima/ima_fs.c')
-rw-r--r--security/integrity/ima/ima_fs.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 0c72c9c3895..3674a52e1cf 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -243,32 +243,34 @@ static const struct file_operations ima_ascii_measurements_ops = {
static ssize_t ima_write_policy(struct file *file, const char __user *buf,
size_t datalen, loff_t *ppos)
{
- char *data;
- int rc;
+ char *data = NULL;
+ ssize_t result;
if (datalen >= PAGE_SIZE)
- return -ENOMEM;
- if (*ppos != 0) {
- /* No partial writes. */
- return -EINVAL;
- }
+ datalen = PAGE_SIZE - 1;
+
+ /* No partial writes. */
+ result = -EINVAL;
+ if (*ppos != 0)
+ goto out;
+
+ result = -ENOMEM;
data = kmalloc(datalen + 1, GFP_KERNEL);
if (!data)
- return -ENOMEM;
+ goto out;
- if (copy_from_user(data, buf, datalen)) {
- kfree(data);
- return -EFAULT;
- }
*(data + datalen) = '\0';
- rc = ima_parse_add_rule(data);
- if (rc < 0) {
- datalen = -EINVAL;
- valid_policy = 0;
- }
+ result = -EFAULT;
+ if (copy_from_user(data, buf, datalen))
+ goto out;
+
+ result = ima_parse_add_rule(data);
+out:
+ if (result < 0)
+ valid_policy = 0;
kfree(data);
- return datalen;
+ return result;
}
static struct dentry *ima_dir;