Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorri...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 25 Oct 2018 20:22:23 +0000 (13:22 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 25 Oct 2018 20:22:23 +0000 (13:22 -0700)
Pull integrity updates from James Morris:
 "From Mimi: This contains a couple of bug fixes, including one for a
  recent problem with calculating file hashes on overlayfs, and some
  code cleanup"

* 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  MAINTAINERS: add Jarkko as maintainer for trusted keys
  ima: open a new file instance if no read permissions
  ima: fix showing large 'violations' or 'runtime_measurements_count'
  security/integrity: remove unnecessary 'init_keyring' variable
  security/integrity: constify some read-only data
  vfs: require i_size <= SIZE_MAX in kernel_read_file()

MAINTAINERS
fs/exec.c
security/integrity/digsig.c
security/integrity/evm/evm_crypto.c
security/integrity/ima/ima.h
security/integrity/ima/ima_api.c
security/integrity/ima/ima_crypto.c
security/integrity/ima/ima_fs.c
security/integrity/ima/ima_init.c
security/integrity/ima/ima_main.c
security/integrity/ima/ima_template.c

index 9a8e039362dc52b3b3a9baa10e8a4f79699f5c9b..99540a5a4e19e9dd06af672dcea7df58f1debbac 100644 (file)
@@ -8165,6 +8165,7 @@ F:        security/keys/encrypted-keys/
 
 KEYS-TRUSTED
 M:     James Bottomley <jejb@linux.vnet.ibm.com>
+M:      Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
 M:     Mimi Zohar <zohar@linux.vnet.ibm.com>
 L:     linux-integrity@vger.kernel.org
 L:     keyrings@vger.kernel.org
index 1ebf6e5a521d9924aa6572bedba504efaf32ee9b..fc281b738a9822a652f7d19bb60ae15acd7a7ebf 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -908,14 +908,14 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
                goto out;
 
        i_size = i_size_read(file_inode(file));
-       if (max_size > 0 && i_size > max_size) {
-               ret = -EFBIG;
-               goto out;
-       }
        if (i_size <= 0) {
                ret = -EINVAL;
                goto out;
        }
+       if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
+               ret = -EFBIG;
+               goto out;
+       }
 
        if (id != READING_FIRMWARE_PREALLOC_BUFFER)
                *buf = vmalloc(i_size);
index 9bb0a7f2863e3750ced13183d083281d320f9109..5eacba858e4be266f9828b6c17dce46691025fd0 100644 (file)
@@ -26,7 +26,7 @@
 
 static struct key *keyring[INTEGRITY_KEYRING_MAX];
 
-static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
+static const char * const keyring_name[INTEGRITY_KEYRING_MAX] = {
 #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING
        "_evm",
        "_ima",
@@ -37,12 +37,6 @@ static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
        "_module",
 };
 
-#ifdef CONFIG_INTEGRITY_TRUSTED_KEYRING
-static bool init_keyring __initdata = true;
-#else
-static bool init_keyring __initdata;
-#endif
-
 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
 #define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
 #else
@@ -85,7 +79,7 @@ int __init integrity_init_keyring(const unsigned int id)
        struct key_restriction *restriction;
        int err = 0;
 
-       if (!init_keyring)
+       if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
                return 0;
 
        restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
index 8a3905bb02c7451a3720b57ab1f93183806b92d8..8c25f949ebdb6082053c4cb8d9e89ec8d8c49e6a 100644 (file)
@@ -27,7 +27,7 @@
 #define EVMKEY "evm-key"
 #define MAX_KEY_SIZE 128
 static unsigned char evmkey[MAX_KEY_SIZE];
-static int evmkey_len = MAX_KEY_SIZE;
+static const int evmkey_len = MAX_KEY_SIZE;
 
 struct crypto_shash *hmac_tfm;
 static struct crypto_shash *evm_tfm[HASH_ALGO__LAST];
@@ -38,7 +38,7 @@ static DEFINE_MUTEX(mutex);
 
 static unsigned long evm_set_key_flags;
 
-static char * const evm_hmac = "hmac(sha1)";
+static const char evm_hmac[] = "hmac(sha1)";
 
 /**
  * evm_set_key() - set EVM HMAC key from the kernel
index 67db9d9454ca8e739a9560198bb9c132c6288206..cc12f3449a728e27030bacb821242ef1c380d746 100644 (file)
@@ -88,7 +88,7 @@ struct ima_template_desc {
        char *name;
        char *fmt;
        int num_fields;
-       struct ima_template_field **fields;
+       const struct ima_template_field **fields;
 };
 
 struct ima_template_entry {
index a02c5acfd403b99edebb3dabdbd38f62e8786931..99dd1d53fc35bea0847416a7140fc46e04150efb 100644 (file)
@@ -51,7 +51,8 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
 
        (*entry)->template_desc = template_desc;
        for (i = 0; i < template_desc->num_fields; i++) {
-               struct ima_template_field *field = template_desc->fields[i];
+               const struct ima_template_field *field =
+                       template_desc->fields[i];
                u32 len;
 
                result = field->field_init(event_data,
index 7e7e7e7c250a3ee7a4c37712d66d3b87327fd3ec..d9e7728027c6c3348d110a66241e480017c2e50d 100644 (file)
@@ -210,7 +210,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
 {
        loff_t i_size, offset;
        char *rbuf[2] = { NULL, };
-       int rc, read = 0, rbuf_len, active = 0, ahash_rc = 0;
+       int rc, rbuf_len, active = 0, ahash_rc = 0;
        struct ahash_request *req;
        struct scatterlist sg[1];
        struct crypto_wait wait;
@@ -257,11 +257,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
                                          &rbuf_size[1], 0);
        }
 
-       if (!(file->f_mode & FMODE_READ)) {
-               file->f_mode |= FMODE_READ;
-               read = 1;
-       }
-
        for (offset = 0; offset < i_size; offset += rbuf_len) {
                if (!rbuf[1] && offset) {
                        /* Not using two buffers, and it is not the first
@@ -300,8 +295,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
        /* wait for the last update request to complete */
        rc = ahash_wait(ahash_rc, &wait);
 out3:
-       if (read)
-               file->f_mode &= ~FMODE_READ;
        ima_free_pages(rbuf[0], rbuf_size[0]);
        ima_free_pages(rbuf[1], rbuf_size[1]);
 out2:
@@ -336,7 +329,7 @@ static int ima_calc_file_hash_tfm(struct file *file,
 {
        loff_t i_size, offset = 0;
        char *rbuf;
-       int rc, read = 0;
+       int rc;
        SHASH_DESC_ON_STACK(shash, tfm);
 
        shash->tfm = tfm;
@@ -357,11 +350,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
        if (!rbuf)
                return -ENOMEM;
 
-       if (!(file->f_mode & FMODE_READ)) {
-               file->f_mode |= FMODE_READ;
-               read = 1;
-       }
-
        while (offset < i_size) {
                int rbuf_len;
 
@@ -378,8 +366,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
                if (rc)
                        break;
        }
-       if (read)
-               file->f_mode &= ~FMODE_READ;
        kfree(rbuf);
 out:
        if (!rc)
@@ -420,6 +406,8 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
 {
        loff_t i_size;
        int rc;
+       struct file *f = file;
+       bool new_file_instance = false, modified_flags = false;
 
        /*
         * For consistency, fail file's opened with the O_DIRECT flag on
@@ -431,15 +419,41 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
                return -EINVAL;
        }
 
-       i_size = i_size_read(file_inode(file));
+       /* Open a new file instance in O_RDONLY if we cannot read */
+       if (!(file->f_mode & FMODE_READ)) {
+               int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
+                               O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL);
+               flags |= O_RDONLY;
+               f = dentry_open(&file->f_path, flags, file->f_cred);
+               if (IS_ERR(f)) {
+                       /*
+                        * Cannot open the file again, lets modify f_flags
+                        * of original and continue
+                        */
+                       pr_info_ratelimited("Unable to reopen file for reading.\n");
+                       f = file;
+                       f->f_flags |= FMODE_READ;
+                       modified_flags = true;
+               } else {
+                       new_file_instance = true;
+               }
+       }
+
+       i_size = i_size_read(file_inode(f));
 
        if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
-               rc = ima_calc_file_ahash(file, hash);
+               rc = ima_calc_file_ahash(f, hash);
                if (!rc)
-                       return 0;
+                       goto out;
        }
 
-       return ima_calc_file_shash(file, hash);
+       rc = ima_calc_file_shash(f, hash);
+out:
+       if (new_file_instance)
+               fput(f);
+       else if (modified_flags)
+               f->f_flags &= ~FMODE_READ;
+       return rc;
 }
 
 /*
index ae9d5c766a3ce9313110fb663178d0840d4eabcd..3183cc23d0f8e09bbc3676910f56f6026a2903b8 100644 (file)
@@ -42,14 +42,14 @@ static int __init default_canonical_fmt_setup(char *str)
 __setup("ima_canonical_fmt", default_canonical_fmt_setup);
 
 static int valid_policy = 1;
-#define TMPBUFLEN 12
+
 static ssize_t ima_show_htable_value(char __user *buf, size_t count,
                                     loff_t *ppos, atomic_long_t *val)
 {
-       char tmpbuf[TMPBUFLEN];
+       char tmpbuf[32];        /* greater than largest 'long' string value */
        ssize_t len;
 
-       len = scnprintf(tmpbuf, TMPBUFLEN, "%li\n", atomic_long_read(val));
+       len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", atomic_long_read(val));
        return simple_read_from_buffer(buf, count, ppos, tmpbuf, len);
 }
 
@@ -179,7 +179,8 @@ int ima_measurements_show(struct seq_file *m, void *v)
        /* 6th:  template specific data */
        for (i = 0; i < e->template_desc->num_fields; i++) {
                enum ima_show_type show = IMA_SHOW_BINARY;
-               struct ima_template_field *field = e->template_desc->fields[i];
+               const struct ima_template_field *field =
+                       e->template_desc->fields[i];
 
                if (is_ima_template && strcmp(field->field_id, "d") == 0)
                        show = IMA_SHOW_BINARY_NO_FIELD_LEN;
index faac9ecaa0aeff26a4a83acb593b79ab4a5c91d7..59d834219cd6173b3e7d2dd2858ea19e3a7d4036 100644 (file)
@@ -25,7 +25,7 @@
 #include "ima.h"
 
 /* name for boot aggregate entry */
-static const char *boot_aggregate_name = "boot_aggregate";
+static const char boot_aggregate_name[] = "boot_aggregate";
 struct tpm_chip *ima_tpm_chip;
 
 /* Add the boot aggregate to the IMA measurement list and extend
index 2d31921fbda4a340f0a65cfd3d4532d8d77f9d82..1b88d58e132586c9d588d959bdc7644186345e80 100644 (file)
@@ -440,7 +440,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
        return 0;
 }
 
-static int read_idmap[READING_MAX_ID] = {
+static const int read_idmap[READING_MAX_ID] = {
        [READING_FIRMWARE] = FIRMWARE_CHECK,
        [READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK,
        [READING_MODULE] = MODULE_CHECK,
index 30db39b2380432b1770f0f03fd84a75d2dfb9cb1..b631b8bc7624016712d8b614ae10b1c1527988cf 100644 (file)
@@ -32,7 +32,7 @@ static struct ima_template_desc builtin_templates[] = {
 static LIST_HEAD(defined_templates);
 static DEFINE_SPINLOCK(template_list);
 
-static struct ima_template_field supported_fields[] = {
+static const struct ima_template_field supported_fields[] = {
        {.field_id = "d", .field_init = ima_eventdigest_init,
         .field_show = ima_show_template_digest},
        {.field_id = "n", .field_init = ima_eventname_init,
@@ -49,7 +49,7 @@ static struct ima_template_field supported_fields[] = {
 static struct ima_template_desc *ima_template;
 static struct ima_template_desc *lookup_template_desc(const char *name);
 static int template_desc_init_fields(const char *template_fmt,
-                                    struct ima_template_field ***fields,
+                                    const struct ima_template_field ***fields,
                                     int *num_fields);
 
 static int __init ima_template_setup(char *str)
@@ -125,7 +125,8 @@ static struct ima_template_desc *lookup_template_desc(const char *name)
        return found ? template_desc : NULL;
 }
 
-static struct ima_template_field *lookup_template_field(const char *field_id)
+static const struct ima_template_field *
+lookup_template_field(const char *field_id)
 {
        int i;
 
@@ -153,11 +154,11 @@ static int template_fmt_size(const char *template_fmt)
 }
 
 static int template_desc_init_fields(const char *template_fmt,
-                                    struct ima_template_field ***fields,
+                                    const struct ima_template_field ***fields,
                                     int *num_fields)
 {
        const char *template_fmt_ptr;
-       struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX];
+       const struct ima_template_field *found_fields[IMA_TEMPLATE_NUM_FIELDS_MAX];
        int template_num_fields;
        int i, len;