1
0
Fork 0

Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

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()
hifive-unleashed-5.1
Linus Torvalds 2018-10-25 13:22:23 -07:00
commit 57ce66d39f
11 changed files with 62 additions and 50 deletions

View File

@ -8165,6 +8165,7 @@ F: security/keys/encrypted-keys/
KEYS-TRUSTED KEYS-TRUSTED
M: James Bottomley <jejb@linux.vnet.ibm.com> M: James Bottomley <jejb@linux.vnet.ibm.com>
M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
M: Mimi Zohar <zohar@linux.vnet.ibm.com> M: Mimi Zohar <zohar@linux.vnet.ibm.com>
L: linux-integrity@vger.kernel.org L: linux-integrity@vger.kernel.org
L: keyrings@vger.kernel.org L: keyrings@vger.kernel.org

View File

@ -908,14 +908,14 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size,
goto out; goto out;
i_size = i_size_read(file_inode(file)); i_size = i_size_read(file_inode(file));
if (max_size > 0 && i_size > max_size) {
ret = -EFBIG;
goto out;
}
if (i_size <= 0) { if (i_size <= 0) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
if (i_size > SIZE_MAX || (max_size > 0 && i_size > max_size)) {
ret = -EFBIG;
goto out;
}
if (id != READING_FIRMWARE_PREALLOC_BUFFER) if (id != READING_FIRMWARE_PREALLOC_BUFFER)
*buf = vmalloc(i_size); *buf = vmalloc(i_size);

View File

@ -26,7 +26,7 @@
static struct key *keyring[INTEGRITY_KEYRING_MAX]; 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 #ifndef CONFIG_INTEGRITY_TRUSTED_KEYRING
"_evm", "_evm",
"_ima", "_ima",
@ -37,12 +37,6 @@ static const char *keyring_name[INTEGRITY_KEYRING_MAX] = {
"_module", "_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 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
#define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted #define restrict_link_to_ima restrict_link_by_builtin_and_secondary_trusted
#else #else
@ -85,7 +79,7 @@ int __init integrity_init_keyring(const unsigned int id)
struct key_restriction *restriction; struct key_restriction *restriction;
int err = 0; int err = 0;
if (!init_keyring) if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING))
return 0; return 0;
restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL);

View File

@ -27,7 +27,7 @@
#define EVMKEY "evm-key" #define EVMKEY "evm-key"
#define MAX_KEY_SIZE 128 #define MAX_KEY_SIZE 128
static unsigned char evmkey[MAX_KEY_SIZE]; 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; struct crypto_shash *hmac_tfm;
static struct crypto_shash *evm_tfm[HASH_ALGO__LAST]; 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 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 * evm_set_key() - set EVM HMAC key from the kernel

View File

@ -88,7 +88,7 @@ struct ima_template_desc {
char *name; char *name;
char *fmt; char *fmt;
int num_fields; int num_fields;
struct ima_template_field **fields; const struct ima_template_field **fields;
}; };
struct ima_template_entry { struct ima_template_entry {

View File

@ -51,7 +51,8 @@ int ima_alloc_init_template(struct ima_event_data *event_data,
(*entry)->template_desc = template_desc; (*entry)->template_desc = template_desc;
for (i = 0; i < template_desc->num_fields; i++) { 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; u32 len;
result = field->field_init(event_data, result = field->field_init(event_data,

View File

@ -210,7 +210,7 @@ static int ima_calc_file_hash_atfm(struct file *file,
{ {
loff_t i_size, offset; loff_t i_size, offset;
char *rbuf[2] = { NULL, }; 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 ahash_request *req;
struct scatterlist sg[1]; struct scatterlist sg[1];
struct crypto_wait wait; struct crypto_wait wait;
@ -257,11 +257,6 @@ static int ima_calc_file_hash_atfm(struct file *file,
&rbuf_size[1], 0); &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) { for (offset = 0; offset < i_size; offset += rbuf_len) {
if (!rbuf[1] && offset) { if (!rbuf[1] && offset) {
/* Not using two buffers, and it is not the first /* 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 */ /* wait for the last update request to complete */
rc = ahash_wait(ahash_rc, &wait); rc = ahash_wait(ahash_rc, &wait);
out3: out3:
if (read)
file->f_mode &= ~FMODE_READ;
ima_free_pages(rbuf[0], rbuf_size[0]); ima_free_pages(rbuf[0], rbuf_size[0]);
ima_free_pages(rbuf[1], rbuf_size[1]); ima_free_pages(rbuf[1], rbuf_size[1]);
out2: out2:
@ -336,7 +329,7 @@ static int ima_calc_file_hash_tfm(struct file *file,
{ {
loff_t i_size, offset = 0; loff_t i_size, offset = 0;
char *rbuf; char *rbuf;
int rc, read = 0; int rc;
SHASH_DESC_ON_STACK(shash, tfm); SHASH_DESC_ON_STACK(shash, tfm);
shash->tfm = tfm; shash->tfm = tfm;
@ -357,11 +350,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
if (!rbuf) if (!rbuf)
return -ENOMEM; return -ENOMEM;
if (!(file->f_mode & FMODE_READ)) {
file->f_mode |= FMODE_READ;
read = 1;
}
while (offset < i_size) { while (offset < i_size) {
int rbuf_len; int rbuf_len;
@ -378,8 +366,6 @@ static int ima_calc_file_hash_tfm(struct file *file,
if (rc) if (rc)
break; break;
} }
if (read)
file->f_mode &= ~FMODE_READ;
kfree(rbuf); kfree(rbuf);
out: out:
if (!rc) if (!rc)
@ -420,6 +406,8 @@ int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash)
{ {
loff_t i_size; loff_t i_size;
int rc; 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 * 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; 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)) {
if (ima_ahash_minsize && i_size >= ima_ahash_minsize) { int flags = file->f_flags & ~(O_WRONLY | O_APPEND |
rc = ima_calc_file_ahash(file, hash); O_TRUNC | O_CREAT | O_NOCTTY | O_EXCL);
if (!rc) flags |= O_RDONLY;
return 0; 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;
}
} }
return ima_calc_file_shash(file, hash); i_size = i_size_read(file_inode(f));
if (ima_ahash_minsize && i_size >= ima_ahash_minsize) {
rc = ima_calc_file_ahash(f, hash);
if (!rc)
goto out;
}
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;
} }
/* /*

View File

@ -42,14 +42,14 @@ static int __init default_canonical_fmt_setup(char *str)
__setup("ima_canonical_fmt", default_canonical_fmt_setup); __setup("ima_canonical_fmt", default_canonical_fmt_setup);
static int valid_policy = 1; static int valid_policy = 1;
#define TMPBUFLEN 12
static ssize_t ima_show_htable_value(char __user *buf, size_t count, static ssize_t ima_show_htable_value(char __user *buf, size_t count,
loff_t *ppos, atomic_long_t *val) loff_t *ppos, atomic_long_t *val)
{ {
char tmpbuf[TMPBUFLEN]; char tmpbuf[32]; /* greater than largest 'long' string value */
ssize_t len; 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); 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 */ /* 6th: template specific data */
for (i = 0; i < e->template_desc->num_fields; i++) { for (i = 0; i < e->template_desc->num_fields; i++) {
enum ima_show_type show = IMA_SHOW_BINARY; 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) if (is_ima_template && strcmp(field->field_id, "d") == 0)
show = IMA_SHOW_BINARY_NO_FIELD_LEN; show = IMA_SHOW_BINARY_NO_FIELD_LEN;

View File

@ -25,7 +25,7 @@
#include "ima.h" #include "ima.h"
/* name for boot aggregate entry */ /* 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; struct tpm_chip *ima_tpm_chip;
/* Add the boot aggregate to the IMA measurement list and extend /* Add the boot aggregate to the IMA measurement list and extend

View File

@ -440,7 +440,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
return 0; return 0;
} }
static int read_idmap[READING_MAX_ID] = { static const int read_idmap[READING_MAX_ID] = {
[READING_FIRMWARE] = FIRMWARE_CHECK, [READING_FIRMWARE] = FIRMWARE_CHECK,
[READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK, [READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK,
[READING_MODULE] = MODULE_CHECK, [READING_MODULE] = MODULE_CHECK,

View File

@ -32,7 +32,7 @@ static struct ima_template_desc builtin_templates[] = {
static LIST_HEAD(defined_templates); static LIST_HEAD(defined_templates);
static DEFINE_SPINLOCK(template_list); 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_id = "d", .field_init = ima_eventdigest_init,
.field_show = ima_show_template_digest}, .field_show = ima_show_template_digest},
{.field_id = "n", .field_init = ima_eventname_init, {.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 *ima_template;
static struct ima_template_desc *lookup_template_desc(const char *name); static struct ima_template_desc *lookup_template_desc(const char *name);
static int template_desc_init_fields(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); int *num_fields);
static int __init ima_template_setup(char *str) 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; 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; 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, static int template_desc_init_fields(const char *template_fmt,
struct ima_template_field ***fields, const struct ima_template_field ***fields,
int *num_fields) int *num_fields)
{ {
const char *template_fmt_ptr; 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 template_num_fields;
int i, len; int i, len;