diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/Kconfig | 38 | ||||
-rw-r--r-- | security/apparmor/apparmorfs.c | 13 | ||||
-rw-r--r-- | security/apparmor/crypto.c | 2 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 49 | ||||
-rw-r--r-- | security/device_cgroup.c | 2 | ||||
-rw-r--r-- | security/inode.c | 13 | ||||
-rw-r--r-- | security/integrity/Kconfig | 11 | ||||
-rw-r--r-- | security/integrity/Makefile | 8 | ||||
-rw-r--r-- | security/integrity/digsig_asymmetric.c | 11 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 1 | ||||
-rw-r--r-- | security/integrity/ima/ima_crypto.c | 4 | ||||
-rw-r--r-- | security/integrity/platform_certs/load_ipl_s390.c | 36 | ||||
-rw-r--r-- | security/keys/dh.c | 1 | ||||
-rw-r--r-- | security/keys/encrypted-keys/encrypted.c | 1 | ||||
-rw-r--r-- | security/keys/trusted.c | 33 | ||||
-rw-r--r-- | security/selinux/include/classmap.h | 1 |
16 files changed, 190 insertions, 34 deletions
diff --git a/security/Kconfig b/security/Kconfig index 1d6463fb1450..353cfef71d4e 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -239,8 +239,46 @@ source "security/safesetid/Kconfig" source "security/integrity/Kconfig" +choice + prompt "First legacy 'major LSM' to be initialized" + default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX + default DEFAULT_SECURITY_SMACK if SECURITY_SMACK + default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO + default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR + default DEFAULT_SECURITY_DAC + + help + This choice is there only for converting CONFIG_DEFAULT_SECURITY + in old kernel configs to CONFIG_LSM in new kernel configs. Don't + change this choice unless you are creating a fresh kernel config, + for this choice will be ignored after CONFIG_LSM has been set. + + Selects the legacy "major security module" that will be + initialized first. Overridden by non-default CONFIG_LSM. + + config DEFAULT_SECURITY_SELINUX + bool "SELinux" if SECURITY_SELINUX=y + + config DEFAULT_SECURITY_SMACK + bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y + + config DEFAULT_SECURITY_TOMOYO + bool "TOMOYO" if SECURITY_TOMOYO=y + + config DEFAULT_SECURITY_APPARMOR + bool "AppArmor" if SECURITY_APPARMOR=y + + config DEFAULT_SECURITY_DAC + bool "Unix Discretionary Access Controls" + +endchoice + config LSM string "Ordered list of enabled LSMs" + default "yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor" if DEFAULT_SECURITY_SMACK + default "yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo" if DEFAULT_SECURITY_APPARMOR + default "yama,loadpin,safesetid,integrity,tomoyo" if DEFAULT_SECURITY_TOMOYO + default "yama,loadpin,safesetid,integrity" if DEFAULT_SECURITY_DAC default "yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" help A comma-separated list of LSMs, in initialization order. diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index fefee040bf79..b9298d2e8165 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -123,17 +123,22 @@ static int aafs_show_path(struct seq_file *seq, struct dentry *dentry) return 0; } -static void aafs_evict_inode(struct inode *inode) +static void aafs_i_callback(struct rcu_head *head) { - truncate_inode_pages_final(&inode->i_data); - clear_inode(inode); + struct inode *inode = container_of(head, struct inode, i_rcu); if (S_ISLNK(inode->i_mode)) kfree(inode->i_link); + free_inode_nonrcu(inode); +} + +static void aafs_destroy_inode(struct inode *inode) +{ + call_rcu(&inode->i_rcu, aafs_i_callback); } static const struct super_operations aafs_super_ops = { .statfs = simple_statfs, - .evict_inode = aafs_evict_inode, + .destroy_inode = aafs_destroy_inode, .show_path = aafs_show_path, }; diff --git a/security/apparmor/crypto.c b/security/apparmor/crypto.c index af03d98c7552..baba63bc66b1 100644 --- a/security/apparmor/crypto.c +++ b/security/apparmor/crypto.c @@ -43,7 +43,6 @@ char *aa_calc_hash(void *data, size_t len) goto fail; desc->tfm = apparmor_tfm; - desc->flags = 0; error = crypto_shash_init(desc); if (error) @@ -81,7 +80,6 @@ int aa_calc_profile_hash(struct aa_profile *profile, u32 version, void *start, goto fail; desc->tfm = apparmor_tfm; - desc->flags = 0; error = crypto_shash_init(desc); if (error) diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 49d664ddff44..87500bde5a92 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1336,9 +1336,16 @@ module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR); bool aa_g_paranoid_load = true; module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO); +static int param_get_aaintbool(char *buffer, const struct kernel_param *kp); +static int param_set_aaintbool(const char *val, const struct kernel_param *kp); +#define param_check_aaintbool param_check_int +static const struct kernel_param_ops param_ops_aaintbool = { + .set = param_set_aaintbool, + .get = param_get_aaintbool +}; /* Boot time disable flag */ static int apparmor_enabled __lsm_ro_after_init = 1; -module_param_named(enabled, apparmor_enabled, int, 0444); +module_param_named(enabled, apparmor_enabled, aaintbool, 0444); static int __init apparmor_enabled_setup(char *str) { @@ -1413,6 +1420,46 @@ static int param_get_aauint(char *buffer, const struct kernel_param *kp) return param_get_uint(buffer, kp); } +/* Can only be set before AppArmor is initialized (i.e. on boot cmdline). */ +static int param_set_aaintbool(const char *val, const struct kernel_param *kp) +{ + struct kernel_param kp_local; + bool value; + int error; + + if (apparmor_initialized) + return -EPERM; + + /* Create local copy, with arg pointing to bool type. */ + value = !!*((int *)kp->arg); + memcpy(&kp_local, kp, sizeof(kp_local)); + kp_local.arg = &value; + + error = param_set_bool(val, &kp_local); + if (!error) + *((int *)kp->arg) = *((bool *)kp_local.arg); + return error; +} + +/* + * To avoid changing /sys/module/apparmor/parameters/enabled from Y/N to + * 1/0, this converts the "int that is actually bool" back to bool for + * display in the /sys filesystem, while keeping it "int" for the LSM + * infrastructure. + */ +static int param_get_aaintbool(char *buffer, const struct kernel_param *kp) +{ + struct kernel_param kp_local; + bool value; + + /* Create local copy, with arg pointing to bool type. */ + value = !!*((int *)kp->arg); + memcpy(&kp_local, kp, sizeof(kp_local)); + kp_local.arg = &value; + + return param_get_bool(buffer, &kp_local); +} + static int param_get_audit(char *buffer, const struct kernel_param *kp) { if (!apparmor_enabled) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index cd97929fac66..dc28914fa72e 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -560,7 +560,7 @@ static int propagate_exception(struct dev_cgroup *devcg_root, devcg->behavior == DEVCG_DEFAULT_ALLOW) { rc = dev_exception_add(devcg, ex); if (rc) - break; + return rc; } else { /* * in the other possible cases: diff --git a/security/inode.c b/security/inode.c index b7772a9b315e..421dd72b5876 100644 --- a/security/inode.c +++ b/security/inode.c @@ -27,17 +27,22 @@ static struct vfsmount *mount; static int mount_count; -static void securityfs_evict_inode(struct inode *inode) +static void securityfs_i_callback(struct rcu_head *head) { - truncate_inode_pages_final(&inode->i_data); - clear_inode(inode); + struct inode *inode = container_of(head, struct inode, i_rcu); if (S_ISLNK(inode->i_mode)) kfree(inode->i_link); + free_inode_nonrcu(inode); +} + +static void securityfs_destroy_inode(struct inode *inode) +{ + call_rcu(&inode->i_rcu, securityfs_i_callback); } static const struct super_operations securityfs_super_operations = { .statfs = simple_statfs, - .evict_inode = securityfs_evict_inode, + .destroy_inode = securityfs_destroy_inode, }; static int fill_super(struct super_block *sb, void *data, int silent) diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig index 2ea4ec9991d5..3ba1168b1756 100644 --- a/security/integrity/Kconfig +++ b/security/integrity/Kconfig @@ -55,13 +55,22 @@ config INTEGRITY_PLATFORM_KEYRING bool "Provide keyring for platform/firmware trusted keys" depends on INTEGRITY_ASYMMETRIC_KEYS depends on SYSTEM_BLACKLIST_KEYRING - depends on EFI help Provide a separate, distinct keyring for platform trusted keys, which the kernel automatically populates during initialization from values provided by the platform for verifying the kexec'ed kerned image and, possibly, the initramfs signature. +config LOAD_UEFI_KEYS + depends on INTEGRITY_PLATFORM_KEYRING + depends on EFI + def_bool y + +config LOAD_IPL_KEYS + depends on INTEGRITY_PLATFORM_KEYRING + depends on S390 + def_bool y + config INTEGRITY_AUDIT bool "Enables integrity auditing support " depends on AUDIT diff --git a/security/integrity/Makefile b/security/integrity/Makefile index 86df9aba8c0f..19faace69644 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile @@ -9,10 +9,10 @@ integrity-y := iint.o integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o -integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \ - platform_certs/efi_parser.o \ - platform_certs/load_uefi.o -obj-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/load_uefi.o +integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o +integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \ + platform_certs/load_uefi.o +integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o $(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar subdir-$(CONFIG_IMA) += ima diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c index d775e03fbbcc..99080871eb9f 100644 --- a/security/integrity/digsig_asymmetric.c +++ b/security/integrity/digsig_asymmetric.c @@ -104,9 +104,16 @@ int asymmetric_verify(struct key *keyring, const char *sig, memset(&pks, 0, sizeof(pks)); - pks.pkey_algo = "rsa"; pks.hash_algo = hash_algo_name[hdr->hash_algo]; - pks.encoding = "pkcs1"; + if (hdr->hash_algo == HASH_ALGO_STREEBOG_256 || + hdr->hash_algo == HASH_ALGO_STREEBOG_512) { + /* EC-RDSA and Streebog should go together. */ + pks.pkey_algo = "ecrdsa"; + pks.encoding = "raw"; + } else { + pks.pkey_algo = "rsa"; + pks.encoding = "pkcs1"; + } pks.digest = (u8 *)data; pks.digest_size = datalen; pks.s = hdr->sig; diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c index c37d08118af5..e11564eb645b 100644 --- a/security/integrity/evm/evm_crypto.c +++ b/security/integrity/evm/evm_crypto.c @@ -124,7 +124,6 @@ out: return ERR_PTR(-ENOMEM); desc->tfm = *tfm; - desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; rc = crypto_shash_init(desc); if (rc) { diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 16a4f45863b1..a32878e10ebc 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -333,7 +333,6 @@ static int ima_calc_file_hash_tfm(struct file *file, SHASH_DESC_ON_STACK(shash, tfm); shash->tfm = tfm; - shash->flags = 0; hash->length = crypto_shash_digestsize(tfm); @@ -469,7 +468,6 @@ static int ima_calc_field_array_hash_tfm(struct ima_field_data *field_data, int rc, i; shash->tfm = tfm; - shash->flags = 0; hash->length = crypto_shash_digestsize(tfm); @@ -591,7 +589,6 @@ static int calc_buffer_shash_tfm(const void *buf, loff_t size, int rc; shash->tfm = tfm; - shash->flags = 0; hash->length = crypto_shash_digestsize(tfm); @@ -664,7 +661,6 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest, SHASH_DESC_ON_STACK(shash, tfm); shash->tfm = tfm; - shash->flags = 0; rc = crypto_shash_init(shash); if (rc != 0) diff --git a/security/integrity/platform_certs/load_ipl_s390.c b/security/integrity/platform_certs/load_ipl_s390.c new file mode 100644 index 000000000000..e769dcb7ea94 --- /dev/null +++ b/security/integrity/platform_certs/load_ipl_s390.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/cred.h> +#include <linux/err.h> +#include <linux/efi.h> +#include <linux/slab.h> +#include <keys/asymmetric-type.h> +#include <keys/system_keyring.h> +#include <asm/boot_data.h> +#include "../integrity.h" + +/* + * Load the certs contained in the IPL report created by the machine loader + * into the platform trusted keyring. + */ +static int __init load_ipl_certs(void) +{ + void *ptr, *end; + unsigned int len; + + if (!ipl_cert_list_addr) + return 0; + /* Copy the certificates to the system keyring */ + ptr = (void *) ipl_cert_list_addr; + end = ptr + ipl_cert_list_size; + while ((void *) ptr < end) { + len = *(unsigned int *) ptr; + ptr += sizeof(unsigned int); + add_to_platform_keyring("IPL:db", ptr, len); + ptr += len; + } + return 0; +} +late_initcall(load_ipl_certs); diff --git a/security/keys/dh.c b/security/keys/dh.c index 711e89d8c415..23f95dec771b 100644 --- a/security/keys/dh.c +++ b/security/keys/dh.c @@ -112,7 +112,6 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname) if (!sdesc) goto out_free_tfm; sdesc->shash.tfm = tfm; - sdesc->shash.flags = 0x0; *sdesc_ret = sdesc; diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 347108f660a1..1b1456b21a93 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c @@ -333,7 +333,6 @@ static int calc_hash(struct crypto_shash *tfm, u8 *digest, int err; desc->tfm = tfm; - desc->flags = 0; err = crypto_shash_digest(desc, buf, buflen, digest); shash_desc_zero(desc); diff --git a/security/keys/trusted.c b/security/keys/trusted.c index bcc9c6ead7fd..a75b2f0f1230 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -55,7 +55,6 @@ static struct sdesc *init_sdesc(struct crypto_shash *alg) if (!sdesc) return ERR_PTR(-ENOMEM); sdesc->shash.tfm = alg; - sdesc->shash.flags = 0x0; return sdesc; } @@ -125,7 +124,7 @@ out: */ int TSS_authhmac(unsigned char *digest, const unsigned char *key, unsigned int keylen, unsigned char *h1, - unsigned char *h2, unsigned char h3, ...) + unsigned char *h2, unsigned int h3, ...) { unsigned char paramdigest[SHA1_DIGEST_SIZE]; struct sdesc *sdesc; @@ -135,13 +134,16 @@ int TSS_authhmac(unsigned char *digest, const unsigned char *key, int ret; va_list argp; + if (!chip) + return -ENODEV; + sdesc = init_sdesc(hashalg); if (IS_ERR(sdesc)) { pr_info("trusted_key: can't alloc %s\n", hash_alg); return PTR_ERR(sdesc); } - c = h3; + c = !!h3; ret = crypto_shash_init(&sdesc->shash); if (ret < 0) goto out; @@ -196,6 +198,9 @@ int TSS_checkhmac1(unsigned char *buffer, va_list argp; int ret; + if (!chip) + return -ENODEV; + bufsize = LOAD32(buffer, TPM_SIZE_OFFSET); tag = LOAD16(buffer, 0); ordinal = command; @@ -363,6 +368,9 @@ int trusted_tpm_send(unsigned char *cmd, size_t buflen) { int rc; + if (!chip) + return -ENODEV; + dump_tpm_buf(cmd); rc = tpm_send(chip, cmd, buflen); dump_tpm_buf(cmd); @@ -429,6 +437,9 @@ int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce) { int ret; + if (!chip) + return -ENODEV; + INIT_BUF(tb); store16(tb, TPM_TAG_RQU_COMMAND); store32(tb, TPM_OIAP_SIZE); @@ -1245,9 +1256,13 @@ static int __init init_trusted(void) { int ret; + /* encrypted_keys.ko depends on successful load of this module even if + * TPM is not used. + */ chip = tpm_default_chip(); if (!chip) - return -ENOENT; + return 0; + ret = init_digests(); if (ret < 0) goto err_put; @@ -1269,10 +1284,12 @@ err_put: static void __exit cleanup_trusted(void) { - put_device(&chip->dev); - kfree(digests); - trusted_shash_release(); - unregister_key_type(&key_type_trusted); + if (chip) { + put_device(&chip->dev); + kfree(digests); + trusted_shash_release(); + unregister_key_type(&key_type_trusted); + } } late_initcall(init_trusted); diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index bd5fe0d3204a..201f7e588a29 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include <linux/capability.h> +#include <linux/socket.h> #define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append", "map" |