From: Dmitry Kasatkin <d.kasat...@samsung.com>

We currently cannot do appraisal or signature vetting of IMA policies
since we currently can only load IMA policies by writing the contents
of the policy directly in, as follows:

cat policy-file > <securityfs>/ima/policy

If we provide the kernel the path to the IMA policy so it can load
the policy itself it'd be able to later appraise or vet the file
signature if it has one.  This patch adds support to load the IMA
policy with a given path as follows:

echo /etc/ima/ima_policy > /sys/kernel/security/ima/policy

Changelog v2:
- Patch description re-written by Luis R. Rodriguez

Signed-off-by: Dmitry Kasatkin <d.kasat...@samsung.com>
Signed-off-by: Mimi Zohar <zo...@linux.vnet.ibm.com>
---
 security/integrity/iint.c       |  4 +---
 security/integrity/ima/ima_fs.c | 39 ++++++++++++++++++++++++++++++++++++++-
 security/integrity/integrity.h  |  2 +-
 3 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/security/integrity/iint.c b/security/integrity/iint.c
index 2de9c82..54b51a4 100644
--- a/security/integrity/iint.c
+++ b/security/integrity/iint.c
@@ -203,10 +203,8 @@ int integrity_kernel_read(struct file *file, loff_t offset,
  * This is function opens a file, allocates the buffer of required
  * size, read entire file content to the buffer and closes the file
  *
- * It is used only by init code.
- *
  */
-int __init integrity_read_file(const char *path, char **data)
+int integrity_read_file(const char *path, char **data)
 {
        struct file *file;
        loff_t size;
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index eebb985..f902b6b 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -258,6 +258,40 @@ static const struct file_operations 
ima_ascii_measurements_ops = {
        .release = seq_release,
 };
 
+static ssize_t ima_read_policy(char *path)
+{
+       char *data, *datap;
+       int rc, size, pathlen = strlen(path);
+       char *p;
+
+       /* remove \n */
+       datap = path;
+       strsep(&datap, "\n");
+
+       rc = integrity_read_file(path, &data);
+       if (rc < 0)
+               return rc;
+
+       size = 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;
+       }
+
+       kfree(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)
 {
@@ -288,7 +322,10 @@ static ssize_t ima_write_policy(struct file *file, const 
char __user *buf,
        if (copy_from_user(data, buf, datalen))
                goto out;
 
-       result = ima_parse_add_rule(data);
+       if (data[0] == '/')
+               result = ima_read_policy(data);
+       else
+               result = ima_parse_add_rule(data);
 out:
        if (result < 0)
                valid_policy = 0;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 5efe2ec..5413f22 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -122,7 +122,7 @@ struct integrity_iint_cache *integrity_iint_find(struct 
inode *inode);
 
 int integrity_kernel_read(struct file *file, loff_t offset,
                          char *addr, unsigned long count);
-int __init integrity_read_file(const char *path, char **data);
+int integrity_read_file(const char *path, char **data);
 
 #define INTEGRITY_KEYRING_EVM          0
 #define INTEGRITY_KEYRING_IMA          1
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to