summaryrefslogtreecommitdiff
path: root/security/integrity/ima/ima_fs.c
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2016-02-26 15:06:41 +1100
committerJames Morris <james.l.morris@oracle.com>2016-02-26 15:06:41 +1100
commit481873d06f2bf2ad732450a3a5fa5b8c2a07ef88 (patch)
treee2d16457d7902795073e4e4ad479798242a0ef80 /security/integrity/ima/ima_fs.c
parent602094428090ea17321afcb5edc572544b7ee368 (diff)
parent95ee08fa373b9ede1059c2f384cfeafe10dcd6bb (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next
Diffstat (limited to 'security/integrity/ima/ima_fs.c')
-rw-r--r--security/integrity/ima/ima_fs.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index f355231997b4..60d011aaec38 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -22,6 +22,7 @@
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/parser.h>
+#include <linux/vmalloc.h>
#include "ima.h"
@@ -258,6 +259,43 @@ static const struct file_operations ima_ascii_measurements_ops = {
.release = seq_release,
};
+static ssize_t ima_read_policy(char *path)
+{
+ void *data;
+ char *datap;
+ loff_t size;
+ int rc, pathlen = strlen(path);
+
+ char *p;
+
+ /* remove \n */
+ datap = path;
+ strsep(&datap, "\n");
+
+ rc = kernel_read_file_from_path(path, &data, &size, 0, READING_POLICY);
+ if (rc < 0) {
+ pr_err("Unable to open file: %s (%d)", path, rc);
+ return rc;
+ }
+
+ datap = data;
+ while (size > 0 && (p = strsep(&datap, "\n"))) {
+ pr_debug("rule: %s\n", p);
+ rc = ima_parse_add_rule(p);
+ if (rc < 0)
+ break;
+ size -= rc;
+ }
+
+ vfree(data);
+ if (rc < 0)
+ return rc;
+ else if (size)
+ return -EINVAL;
+ else
+ return pathlen;
+}
+
static ssize_t ima_write_policy(struct file *file, const char __user *buf,
size_t datalen, loff_t *ppos)
{
@@ -286,9 +324,20 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
result = mutex_lock_interruptible(&ima_write_mutex);
if (result < 0)
goto out_free;
- result = ima_parse_add_rule(data);
- mutex_unlock(&ima_write_mutex);
+ if (data[0] == '/') {
+ result = ima_read_policy(data);
+ } else if (ima_appraise & IMA_APPRAISE_POLICY) {
+ pr_err("IMA: signed policy file (specified as an absolute pathname) required\n");
+ integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL,
+ "policy_update", "signed policy required",
+ 1, 0);
+ if (ima_appraise & IMA_APPRAISE_ENFORCE)
+ result = -EACCES;
+ } else {
+ result = ima_parse_add_rule(data);
+ }
+ mutex_unlock(&ima_write_mutex);
out_free:
kfree(data);
out: