|
|
@@ -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,12 @@ 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
|
|
|
+ result = ima_parse_add_rule(data);
|
|
|
+ mutex_unlock(&ima_write_mutex);
|
|
|
out_free:
|
|
|
kfree(data);
|
|
|
out:
|