diff options
author | James Morris <james.l.morris@oracle.com> | 2016-02-26 15:06:41 +1100 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2016-02-26 15:06:41 +1100 |
commit | 481873d06f2bf2ad732450a3a5fa5b8c2a07ef88 (patch) | |
tree | e2d16457d7902795073e4e4ad479798242a0ef80 /security/integrity/ima/ima_fs.c | |
parent | 602094428090ea17321afcb5edc572544b7ee368 (diff) | |
parent | 95ee08fa373b9ede1059c2f384cfeafe10dcd6bb (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.c | 53 |
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: |