diff options
Diffstat (limited to '')
-rw-r--r-- | security/integrity/digsig.c | 10 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 4 | ||||
-rw-r--r-- | security/integrity/ima/ima.h | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_api.c | 3 | ||||
-rw-r--r-- | security/integrity/ima/ima_crypto.c | 54 | ||||
-rw-r--r-- | security/integrity/ima/ima_fs.c | 9 | ||||
-rw-r--r-- | security/integrity/ima/ima_init.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_template.c | 11 | ||||
-rw-r--r-- | security/loadpin/Kconfig | 4 | ||||
-rw-r--r-- | security/loadpin/loadpin.c | 26 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 15 | ||||
-rw-r--r-- | security/smack/smackfs.c | 3 |
13 files changed, 82 insertions, 63 deletions
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 9bb0a7f2863e..5eacba858e4b 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -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); diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index 8a3905bb02c7..8c25f949ebdb 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -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 diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 67db9d9454ca..cc12f3449a72 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -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 { diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index a02c5acfd403..99dd1d53fc35 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -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, diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 7e7e7e7c250a..d9e7728027c6 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -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; } /* diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index ae9d5c766a3c..3183cc23d0f8 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c @@ -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; diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index faac9ecaa0ae..59d834219cd6 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -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 diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 2d31921fbda4..1b88d58e1325 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -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, diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 30db39b23804..b631b8bc7624 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -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; diff --git a/security/loadpin/Kconfig b/security/loadpin/Kconfig index dd01aa91e521..a0d70d82b98e 100644 --- a/security/loadpin/Kconfig +++ b/security/loadpin/Kconfig @@ -10,10 +10,10 @@ config SECURITY_LOADPIN have a root filesystem backed by a read-only device such as dm-verity or a CDROM. -config SECURITY_LOADPIN_ENABLED +config SECURITY_LOADPIN_ENFORCE bool "Enforce LoadPin at boot" depends on SECURITY_LOADPIN help If selected, LoadPin will enforce pinning at boot. If not selected, it can be enabled at boot with the kernel parameter - "loadpin.enabled=1". + "loadpin.enforce=1". diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index 0716af28808a..48f39631b370 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -44,7 +44,7 @@ static void report_load(const char *origin, struct file *file, char *operation) kfree(pathname); } -static int enabled = IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENABLED); +static int enforce = IS_ENABLED(CONFIG_SECURITY_LOADPIN_ENFORCE); static struct super_block *pinned_root; static DEFINE_SPINLOCK(pinned_root_spinlock); @@ -60,8 +60,8 @@ static struct ctl_path loadpin_sysctl_path[] = { static struct ctl_table loadpin_sysctl_table[] = { { - .procname = "enabled", - .data = &enabled, + .procname = "enforce", + .data = &enforce, .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec_minmax, @@ -84,8 +84,11 @@ static void check_pinning_enforcement(struct super_block *mnt_sb) * device, allow sysctl to change modes for testing. */ if (mnt_sb->s_bdev) { + char bdev[BDEVNAME_SIZE]; + ro = bdev_read_only(mnt_sb->s_bdev); - pr_info("dev(%u,%u): %s\n", + bdevname(mnt_sb->s_bdev, bdev); + pr_info("%s (%u:%u): %s\n", bdev, MAJOR(mnt_sb->s_bdev->bd_dev), MINOR(mnt_sb->s_bdev->bd_dev), ro ? "read-only" : "writable"); @@ -97,7 +100,7 @@ static void check_pinning_enforcement(struct super_block *mnt_sb) loadpin_sysctl_table)) pr_notice("sysctl registration failed!\n"); else - pr_info("load pinning can be disabled.\n"); + pr_info("enforcement can be disabled.\n"); } else pr_info("load pinning engaged.\n"); } @@ -128,7 +131,7 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id) /* This handles the older init_module API that has a NULL file. */ if (!file) { - if (!enabled) { + if (!enforce) { report_load(origin, NULL, "old-api-pinning-ignored"); return 0; } @@ -151,7 +154,7 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id) * Unlock now since it's only pinned_root we care about. * In the worst case, we will (correctly) report pinning * failures before we have announced that pinning is - * enabled. This would be purely cosmetic. + * enforcing. This would be purely cosmetic. */ spin_unlock(&pinned_root_spinlock); check_pinning_enforcement(pinned_root); @@ -161,7 +164,7 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id) } if (IS_ERR_OR_NULL(pinned_root) || load_root != pinned_root) { - if (unlikely(!enabled)) { + if (unlikely(!enforce)) { report_load(origin, file, "pinning-ignored"); return 0; } @@ -186,10 +189,11 @@ static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { void __init loadpin_add_hooks(void) { - pr_info("ready to pin (currently %sabled)", enabled ? "en" : "dis"); + pr_info("ready to pin (currently %senforcing)\n", + enforce ? "" : "not "); security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); } /* Should not be mutable after boot, so not listed in sysfs (perm == 0). */ -module_param(enabled, int, 0); -MODULE_PARM_DESC(enabled, "Pin module/firmware loading (default: true)"); +module_param(enforce, int, 0); +MODULE_PARM_DESC(enforce, "Enforce module/firmware pinning"); diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 934dabe150fa..81fb4c1631e9 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -421,6 +421,7 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, struct smk_audit_info ad, *saip = NULL; struct task_smack *tsp; struct smack_known *tracer_known; + const struct cred *tracercred; if ((mode & PTRACE_MODE_NOAUDIT) == 0) { smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK); @@ -429,7 +430,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, } rcu_read_lock(); - tsp = __task_cred(tracer)->security; + tracercred = __task_cred(tracer); + tsp = tracercred->security; tracer_known = smk_of_task(tsp); if ((mode & PTRACE_MODE_ATTACH) && @@ -439,7 +441,7 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, rc = 0; else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN) rc = -EACCES; - else if (capable(CAP_SYS_PTRACE)) + else if (smack_privileged_cred(CAP_SYS_PTRACE, tracercred)) rc = 0; else rc = -EACCES; @@ -1841,6 +1843,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, { struct smack_known *skp; struct smack_known *tkp = smk_of_task(tsk->cred->security); + const struct cred *tcred; struct file *file; int rc; struct smk_audit_info ad; @@ -1854,8 +1857,12 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, skp = file->f_security; rc = smk_access(skp, tkp, MAY_DELIVER, NULL); rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc); - if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) + + rcu_read_lock(); + tcred = __task_cred(tsk); + if (rc != 0 && smack_privileged_cred(CAP_MAC_OVERRIDE, tcred)) rc = 0; + rcu_read_unlock(); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, tsk); @@ -3467,7 +3474,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ final = &smack_known_star; /* - * No break. + * Fall through. * * If a smack value has been set we want to use it, * but since tmpfs isn't giving us the opportunity diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index f6482e53d55a..06b517075ec0 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -2853,7 +2853,6 @@ static const struct file_operations smk_ptrace_ops = { static int smk_fill_super(struct super_block *sb, void *data, int silent) { int rc; - struct inode *root_inode; static const struct tree_descr smack_files[] = { [SMK_LOAD] = { @@ -2917,8 +2916,6 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) return rc; } - root_inode = d_inode(sb->s_root); - return 0; } |