diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2009-02-04 17:07:00 +0300 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2009-02-06 01:05:31 +0300 |
commit | 4af4662fa4a9dc62289c580337ae2506339c4729 (patch) | |
tree | faec95258d2456eb35515f289eb688914ce3b54f /security/integrity/ima/ima_fs.c | |
parent | bab739378758a1e2b2d7ddcee7bc06cf4c591c3c (diff) | |
download | linux-4af4662fa4a9dc62289c580337ae2506339c4729.tar.xz |
integrity: IMA policy
Support for a user loadable policy through securityfs
with support for LSM specific policy data.
- free invalid rule in ima_parse_add_rule()
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Acked-by: Serge Hallyn <serue@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.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 4f25be768b50..95ef1caa64b5 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -19,9 +19,11 @@ #include <linux/seq_file.h> #include <linux/rculist.h> #include <linux/rcupdate.h> +#include <linux/parser.h> #include "ima.h" +static int valid_policy = 1; #define TMPBUFLEN 12 static ssize_t ima_show_htable_value(char __user *buf, size_t count, loff_t *ppos, atomic_long_t *val) @@ -237,11 +239,66 @@ static struct file_operations ima_ascii_measurements_ops = { .release = seq_release, }; +static ssize_t ima_write_policy(struct file *file, const char __user *buf, + size_t datalen, loff_t *ppos) +{ + char *data; + int rc; + + if (datalen >= PAGE_SIZE) + return -ENOMEM; + if (*ppos != 0) { + /* No partial writes. */ + return -EINVAL; + } + data = kmalloc(datalen + 1, GFP_KERNEL); + if (!data) + return -ENOMEM; + + 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; + } + + kfree(data); + return datalen; +} + static struct dentry *ima_dir; static struct dentry *binary_runtime_measurements; static struct dentry *ascii_runtime_measurements; static struct dentry *runtime_measurements_count; static struct dentry *violations; +static struct dentry *ima_policy; + +/* + * ima_release_policy - start using the new measure policy rules. + * + * Initially, ima_measure points to the default policy rules, now + * point to the new policy rules, and remove the securityfs policy file. + */ +static int ima_release_policy(struct inode *inode, struct file *file) +{ + if (!valid_policy) { + ima_delete_rules(); + return 0; + } + ima_update_policy(); + securityfs_remove(ima_policy); + ima_policy = NULL; + return 0; +} + +static struct file_operations ima_measure_policy_ops = { + .write = ima_write_policy, + .release = ima_release_policy +}; int ima_fs_init(void) { @@ -276,13 +333,20 @@ int ima_fs_init(void) if (IS_ERR(violations)) goto out; - return 0; + ima_policy = securityfs_create_file("policy", + S_IRUSR | S_IRGRP | S_IWUSR, + ima_dir, NULL, + &ima_measure_policy_ops); + if (IS_ERR(ima_policy)) + goto out; + return 0; out: securityfs_remove(runtime_measurements_count); securityfs_remove(ascii_runtime_measurements); securityfs_remove(binary_runtime_measurements); securityfs_remove(ima_dir); + securityfs_remove(ima_policy); return -1; } @@ -293,4 +357,5 @@ void __exit ima_fs_cleanup(void) securityfs_remove(ascii_runtime_measurements); securityfs_remove(binary_runtime_measurements); securityfs_remove(ima_dir); + securityfs_remove(ima_policy); } |