integrity: use kernel_read_file_from_path() to read x509 certs
authorChristoph Hellwig <hch@lst.de>
Sun, 10 Sep 2017 07:49:45 +0000 (09:49 +0200)
committerMimi Zohar <zohar@linux.vnet.ibm.com>
Wed, 8 Nov 2017 20:16:36 +0000 (15:16 -0500)
The CONFIG_IMA_LOAD_X509 and CONFIG_EVM_LOAD_X509 options permit
loading x509 signed certificates onto the trusted keyrings without
verifying the x509 certificate file's signature.

This patch replaces the call to the integrity_read_file() specific
function with the common kernel_read_file_from_path() function.
To avoid verifying the file signature, this patch defines
READING_X509_CERTFICATE.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
include/linux/fs.h
security/integrity/digsig.c
security/integrity/iint.c
security/integrity/ima/ima_main.c
security/integrity/integrity.h

index 339e737..4563250 100644 (file)
@@ -2792,6 +2792,7 @@ extern int do_pipe_flags(int *, int);
        id(KEXEC_IMAGE, kexec-image)            \
        id(KEXEC_INITRAMFS, kexec-initramfs)    \
        id(POLICY, security-policy)             \
+       id(X509_CERTIFICATE, x509-certificate)  \
        id(MAX_ID, )
 
 #define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
index 06554c4..6f9e4ce 100644 (file)
@@ -112,21 +112,25 @@ int __init integrity_init_keyring(const unsigned int id)
 int __init integrity_load_x509(const unsigned int id, const char *path)
 {
        key_ref_t key;
-       char *data;
+       void *data;
+       loff_t size;
        int rc;
 
        if (!keyring[id])
                return -EINVAL;
 
-       rc = integrity_read_file(path, &data);
-       if (rc < 0)
+       rc = kernel_read_file_from_path(path, &data, &size, 0,
+                                       READING_X509_CERTIFICATE);
+       if (rc < 0) {
+               pr_err("Unable to open file: %s (%d)", path, rc);
                return rc;
+       }
 
        key = key_create_or_update(make_key_ref(keyring[id], 1),
                                   "asymmetric",
                                   NULL,
                                   data,
-                                  rc,
+                                  size,
                                   ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
                                    KEY_USR_VIEW | KEY_USR_READ),
                                   KEY_ALLOC_NOT_IN_QUOTA);
@@ -139,6 +143,6 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
                          key_ref_to_ptr(key)->description, path);
                key_ref_put(key);
        }
-       kfree(data);
+       vfree(data);
        return 0;
 }
index 6fc888c..c84e058 100644 (file)
@@ -200,55 +200,6 @@ int integrity_kernel_read(struct file *file, loff_t offset,
 }
 
 /*
- * integrity_read_file - read entire file content into the buffer
- *
- * 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)
-{
-       struct file *file;
-       loff_t size;
-       char *buf;
-       int rc = -EINVAL;
-
-       if (!path || !*path)
-               return -EINVAL;
-
-       file = filp_open(path, O_RDONLY, 0);
-       if (IS_ERR(file)) {
-               rc = PTR_ERR(file);
-               pr_err("Unable to open file: %s (%d)", path, rc);
-               return rc;
-       }
-
-       size = i_size_read(file_inode(file));
-       if (size <= 0)
-               goto out;
-
-       buf = kmalloc(size, GFP_KERNEL);
-       if (!buf) {
-               rc = -ENOMEM;
-               goto out;
-       }
-
-       rc = integrity_kernel_read(file, 0, buf, size);
-       if (rc == size) {
-               *data = buf;
-       } else {
-               kfree(buf);
-               if (rc >= 0)
-                       rc = -EIO;
-       }
-out:
-       fput(file);
-       return rc;
-}
-
-/*
  * integrity_load_keys - load integrity keys hook
  *
  * Hooks is called from init/main.c:kernel_init_freeable()
index 12738c8..d47f92e 100644 (file)
@@ -405,6 +405,10 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
        if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
                return 0;
 
+       /* permit signed certs */
+       if (!file && read_id == READING_X509_CERTIFICATE)
+               return 0;
+
        if (!file || !buf || size == 0) { /* should never happen */
                if (ima_appraise & IMA_APPRAISE_ENFORCE)
                        return -EACCES;
index a53e7e4..e1bf040 100644 (file)
@@ -120,8 +120,6 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode);
 int integrity_kernel_read(struct file *file, loff_t offset,
                          void *addr, unsigned long count);
 
-int __init integrity_read_file(const char *path, char **data);
-
 #define INTEGRITY_KEYRING_EVM          0
 #define INTEGRITY_KEYRING_IMA          1
 #define INTEGRITY_KEYRING_MODULE       2