aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig3
-rw-r--r--security/Kconfig.hardening165
-rw-r--r--security/apparmor/Kconfig1
-rw-r--r--security/apparmor/apparmorfs.c7
-rw-r--r--security/apparmor/crypto.c2
-rw-r--r--security/commoncap.c7
-rw-r--r--security/inode.c7
-rw-r--r--security/integrity/Kconfig12
-rw-r--r--security/integrity/Makefile8
-rw-r--r--security/integrity/digsig_asymmetric.c11
-rw-r--r--security/integrity/evm/Kconfig1
-rw-r--r--security/integrity/evm/Makefile1
-rw-r--r--security/integrity/evm/evm_crypto.c1
-rw-r--r--security/integrity/evm/evm_secfs.c10
-rw-r--r--security/integrity/ima/Kconfig1
-rw-r--r--security/integrity/ima/ima_crypto.c4
-rw-r--r--security/integrity/ima/ima_kexec.c6
-rw-r--r--security/integrity/platform_certs/load_ipl_s390.c36
-rw-r--r--security/keys/Kconfig1
-rw-r--r--security/keys/big_key.c6
-rw-r--r--security/keys/compat.c6
-rw-r--r--security/keys/compat_dh.c6
-rw-r--r--security/keys/dh.c7
-rw-r--r--security/keys/encrypted-keys/encrypted.c1
-rw-r--r--security/keys/gc.c6
-rw-r--r--security/keys/internal.h6
-rw-r--r--security/keys/key.c6
-rw-r--r--security/keys/keyctl.c6
-rw-r--r--security/keys/keyctl_pkey.c6
-rw-r--r--security/keys/keyring.c6
-rw-r--r--security/keys/permission.c6
-rw-r--r--security/keys/persistent.c6
-rw-r--r--security/keys/proc.c6
-rw-r--r--security/keys/process_keys.c47
-rw-r--r--security/keys/request_key.c20
-rw-r--r--security/keys/request_key_auth.c6
-rw-r--r--security/keys/sysctl.c6
-rw-r--r--security/keys/trusted.c1
-rw-r--r--security/keys/user_defined.c6
-rw-r--r--security/loadpin/Kconfig1
-rw-r--r--security/loadpin/Makefile1
-rw-r--r--security/safesetid/Kconfig1
-rw-r--r--security/security.c17
-rw-r--r--security/selinux/Kconfig1
-rw-r--r--security/selinux/hooks.c235
-rw-r--r--security/selinux/include/classmap.h1
-rw-r--r--security/selinux/include/netlabel.h16
-rw-r--r--security/selinux/include/security.h1
-rw-r--r--security/selinux/netlabel.c30
-rw-r--r--security/selinux/ss/services.c7
-rw-r--r--security/smack/Kconfig1
-rw-r--r--security/smack/Makefile1
-rw-r--r--security/smack/smack.h1
-rw-r--r--security/smack/smack_lsm.c34
-rw-r--r--security/smack/smackfs.c55
-rw-r--r--security/tomoyo/Kconfig11
-rw-r--r--security/tomoyo/common.c13
-rw-r--r--security/tomoyo/network.c4
-rw-r--r--security/tomoyo/realpath.c3
-rw-r--r--security/tomoyo/util.c2
-rw-r--r--security/yama/Kconfig1
-rw-r--r--security/yama/Makefile1
62 files changed, 557 insertions, 331 deletions
diff --git a/security/Kconfig b/security/Kconfig
index 353cfef71d4e..466cc1f8ffed 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
# Security configuration
#
@@ -287,5 +288,7 @@ config LSM
If unsure, leave this as the default.
+source "security/Kconfig.hardening"
+
endmenu
diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
new file mode 100644
index 000000000000..c6cb2d9b2905
--- /dev/null
+++ b/security/Kconfig.hardening
@@ -0,0 +1,165 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "Kernel hardening options"
+
+config GCC_PLUGIN_STRUCTLEAK
+ bool
+ help
+ While the kernel is built with warnings enabled for any missed
+ stack variable initializations, this warning is silenced for
+ anything passed by reference to another function, under the
+ occasionally misguided assumption that the function will do
+ the initialization. As this regularly leads to exploitable
+ flaws, this plugin is available to identify and zero-initialize
+ such variables, depending on the chosen level of coverage.
+
+ This plugin was originally ported from grsecurity/PaX. More
+ information at:
+ * https://grsecurity.net/
+ * https://pax.grsecurity.net/
+
+menu "Memory initialization"
+
+config CC_HAS_AUTO_VAR_INIT
+ def_bool $(cc-option,-ftrivial-auto-var-init=pattern)
+
+choice
+ prompt "Initialize kernel stack variables at function entry"
+ default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL if COMPILE_TEST && GCC_PLUGINS
+ default INIT_STACK_ALL if COMPILE_TEST && CC_HAS_AUTO_VAR_INIT
+ default INIT_STACK_NONE
+ help
+ This option enables initialization of stack variables at
+ function entry time. This has the possibility to have the
+ greatest coverage (since all functions can have their
+ variables initialized), but the performance impact depends
+ on the function calling complexity of a given workload's
+ syscalls.
+
+ This chooses the level of coverage over classes of potentially
+ uninitialized variables. The selected class will be
+ initialized before use in a function.
+
+ config INIT_STACK_NONE
+ bool "no automatic initialization (weakest)"
+ help
+ Disable automatic stack variable initialization.
+ This leaves the kernel vulnerable to the standard
+ classes of uninitialized stack variable exploits
+ and information exposures.
+
+ config GCC_PLUGIN_STRUCTLEAK_USER
+ bool "zero-init structs marked for userspace (weak)"
+ depends on GCC_PLUGINS
+ select GCC_PLUGIN_STRUCTLEAK
+ help
+ Zero-initialize any structures on the stack containing
+ a __user attribute. This can prevent some classes of
+ uninitialized stack variable exploits and information
+ exposures, like CVE-2013-2141:
+ https://git.kernel.org/linus/b9e146d8eb3b9eca
+
+ config GCC_PLUGIN_STRUCTLEAK_BYREF
+ bool "zero-init structs passed by reference (strong)"
+ depends on GCC_PLUGINS
+ select GCC_PLUGIN_STRUCTLEAK
+ help
+ Zero-initialize any structures on the stack that may
+ be passed by reference and had not already been
+ explicitly initialized. This can prevent most classes
+ of uninitialized stack variable exploits and information
+ exposures, like CVE-2017-1000410:
+ https://git.kernel.org/linus/06e7e776ca4d3654
+
+ config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
+ bool "zero-init anything passed by reference (very strong)"
+ depends on GCC_PLUGINS
+ select GCC_PLUGIN_STRUCTLEAK
+ help
+ Zero-initialize any stack variables that may be passed
+ by reference and had not already been explicitly
+ initialized. This is intended to eliminate all classes
+ of uninitialized stack variable exploits and information
+ exposures.
+
+ config INIT_STACK_ALL
+ bool "0xAA-init everything on the stack (strongest)"
+ depends on CC_HAS_AUTO_VAR_INIT
+ help
+ Initializes everything on the stack with a 0xAA
+ pattern. This is intended to eliminate all classes
+ of uninitialized stack variable exploits and information
+ exposures, even variables that were warned to have been
+ left uninitialized.
+
+endchoice
+
+config GCC_PLUGIN_STRUCTLEAK_VERBOSE
+ bool "Report forcefully initialized variables"
+ depends on GCC_PLUGIN_STRUCTLEAK
+ depends on !COMPILE_TEST # too noisy
+ help
+ This option will cause a warning to be printed each time the
+ structleak plugin finds a variable it thinks needs to be
+ initialized. Since not all existing initializers are detected
+ by the plugin, this can produce false positive warnings.
+
+config GCC_PLUGIN_STACKLEAK
+ bool "Poison kernel stack before returning from syscalls"
+ depends on GCC_PLUGINS
+ depends on HAVE_ARCH_STACKLEAK
+ help
+ This option makes the kernel erase the kernel stack before
+ returning from system calls. This has the effect of leaving
+ the stack initialized to the poison value, which both reduces
+ the lifetime of any sensitive stack contents and reduces
+ potential for uninitialized stack variable exploits or information
+ exposures (it does not cover functions reaching the same stack
+ depth as prior functions during the same syscall). This blocks
+ most uninitialized stack variable attacks, with the performance
+ impact being driven by the depth of the stack usage, rather than
+ the function calling complexity.
+
+ The performance impact on a single CPU system kernel compilation
+ sees a 1% slowdown, other systems and workloads may vary and you
+ are advised to test this feature on your expected workload before
+ deploying it.
+
+ This plugin was ported from grsecurity/PaX. More information at:
+ * https://grsecurity.net/
+ * https://pax.grsecurity.net/
+
+config STACKLEAK_TRACK_MIN_SIZE
+ int "Minimum stack frame size of functions tracked by STACKLEAK"
+ default 100
+ range 0 4096
+ depends on GCC_PLUGIN_STACKLEAK
+ help
+ The STACKLEAK gcc plugin instruments the kernel code for tracking
+ the lowest border of the kernel stack (and for some other purposes).
+ It inserts the stackleak_track_stack() call for the functions with
+ a stack frame size greater than or equal to this parameter.
+ If unsure, leave the default value 100.
+
+config STACKLEAK_METRICS
+ bool "Show STACKLEAK metrics in the /proc file system"
+ depends on GCC_PLUGIN_STACKLEAK
+ depends on PROC_FS
+ help
+ If this is set, STACKLEAK metrics for every task are available in
+ the /proc file system. In particular, /proc/<pid>/stack_depth
+ shows the maximum kernel stack consumption for the current and
+ previous syscalls. Although this information is not precise, it
+ can be useful for estimating the STACKLEAK performance impact for
+ your workloads.
+
+config STACKLEAK_RUNTIME_DISABLE
+ bool "Allow runtime disabling of kernel stack erasing"
+ depends on GCC_PLUGIN_STACKLEAK
+ help
+ This option provides 'stack_erasing' sysctl, which can be used in
+ runtime to control kernel stack erasing for kernels built with
+ CONFIG_GCC_PLUGIN_STACKLEAK.
+
+endmenu
+
+endmenu
diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig
index 3de21f46c82a..d8b1a360a636 100644
--- a/security/apparmor/Kconfig
+++ b/security/apparmor/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_APPARMOR
bool "AppArmor support"
depends on SECURITY && NET
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index fefee040bf79..9ab5613fe07c 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -123,17 +123,16 @@ 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_free_inode(struct inode *inode)
{
- truncate_inode_pages_final(&inode->i_data);
- clear_inode(inode);
if (S_ISLNK(inode->i_mode))
kfree(inode->i_link);
+ free_inode_nonrcu(inode);
}
static const struct super_operations aafs_super_ops = {
.statfs = simple_statfs,
- .evict_inode = aafs_evict_inode,
+ .free_inode = aafs_free_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/commoncap.c b/security/commoncap.c
index c477fb673701..c0b9664ee49e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -1,10 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Common capabilities, needed by capability.o.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
*/
#include <linux/capability.h>
diff --git a/security/inode.c b/security/inode.c
index b7772a9b315e..aacc4dabba7d 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -27,17 +27,16 @@
static struct vfsmount *mount;
static int mount_count;
-static void securityfs_evict_inode(struct inode *inode)
+static void securityfs_free_inode(struct inode *inode)
{
- truncate_inode_pages_final(&inode->i_data);
- clear_inode(inode);
if (S_ISLNK(inode->i_mode))
kfree(inode->i_link);
+ free_inode_nonrcu(inode);
}
static const struct super_operations securityfs_super_operations = {
.statfs = simple_statfs,
- .evict_inode = securityfs_evict_inode,
+ .free_inode = securityfs_free_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..c352532b8f84 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
config INTEGRITY
bool "Integrity subsystem"
@@ -55,13 +56,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/Kconfig b/security/integrity/evm/Kconfig
index 60221852b26a..a6e19d23e700 100644
--- a/security/integrity/evm/Kconfig
+++ b/security/integrity/evm/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config EVM
bool "EVM support"
select KEYS
diff --git a/security/integrity/evm/Makefile b/security/integrity/evm/Makefile
index 7393c415a066..a56f5613be79 100644
--- a/security/integrity/evm/Makefile
+++ b/security/integrity/evm/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for building the Extended Verification Module(EVM)
#
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/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index 015aea8fdf1e..3f7cbb238923 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -192,7 +192,8 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
if (count > XATTR_NAME_MAX)
return -E2BIG;
- ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_EVM_XATTR);
+ ab = audit_log_start(audit_context(), GFP_KERNEL,
+ AUDIT_INTEGRITY_EVM_XATTR);
if (!ab)
return -ENOMEM;
@@ -214,6 +215,9 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
if (len && xattr->name[len-1] == '\n')
xattr->name[len-1] = '\0';
+ audit_log_format(ab, "xattr=");
+ audit_log_untrustedstring(ab, xattr->name);
+
if (strcmp(xattr->name, ".") == 0) {
evm_xattrs_locked = 1;
newattrs.ia_mode = S_IFREG | 0440;
@@ -222,15 +226,11 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
inode_lock(inode);
err = simple_setattr(evm_xattrs, &newattrs);
inode_unlock(inode);
- audit_log_format(ab, "locked");
if (!err)
err = count;
goto out;
}
- audit_log_format(ab, "xattr=");
- audit_log_untrustedstring(ab, xattr->name);
-
if (strncmp(xattr->name, XATTR_SECURITY_PREFIX,
XATTR_SECURITY_PREFIX_LEN) != 0) {
err = -EINVAL;
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index a18f8c6d13b5..2692c7358c2c 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
# IBM Integrity Measurement Architecture
#
config IMA
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/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
index d6f32807b347..9e94eca48b89 100644
--- a/security/integrity/ima/ima_kexec.c
+++ b/security/integrity/ima/ima_kexec.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2016 IBM Corporation
*
* Authors:
* Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>
* Mimi Zohar <zohar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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/Kconfig b/security/keys/Kconfig
index 6462e6654ccf..ee502e4d390b 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
# Key management configuration
#
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index 2806e70d7f8f..001abe530a0d 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Large capacity key type
*
* Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
*/
#define pr_fmt(fmt) "big_key: "fmt
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 9482df601dc3..35ce47ce2285 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* 32-bit compatibility syscall for 64-bit systems
*
* Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/syscalls.h>
diff --git a/security/keys/compat_dh.c b/security/keys/compat_dh.c
index aa6b34cafe5f..19384e7e976c 100644
--- a/security/keys/compat_dh.c
+++ b/security/keys/compat_dh.c
@@ -1,11 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* 32-bit compatibility syscall for 64-bit systems for DH operations
*
* Copyright (C) 2016 Stephan Mueller <smueller@chronox.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/uaccess.h>
diff --git a/security/keys/dh.c b/security/keys/dh.c
index 711e89d8c415..c4c629bb1c03 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -1,11 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Crypto operations using stored keys
*
* Copyright (c) 2016, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/slab.h>
@@ -112,7 +108,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/gc.c b/security/keys/gc.c
index 634e96b380e8..44e58a3e5663 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Key garbage collector
*
* Copyright (C) 2009-2011 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
*/
#include <linux/slab.h>
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 8f533c81aa8d..d59bc25a9249 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -1,12 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Authentication token and access key management internal defs
*
* Copyright (C) 2003-5, 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#ifndef _INTERNAL_H
diff --git a/security/keys/key.c b/security/keys/key.c
index 696f1c092c50..9a6108aefae9 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Basic authentication token and access key management
*
* Copyright (C) 2004-2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/export.h>
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 3e4053a217c3..5aa605ef8d9d 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Userspace key control operations
*
* Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/init.h>
diff --git a/security/keys/keyctl_pkey.c b/security/keys/keyctl_pkey.c
index 8bdea5abad11..931d8dfb4a7f 100644
--- a/security/keys/keyctl_pkey.c
+++ b/security/keys/keyctl_pkey.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Public-key operation keyctls
*
* Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
*/
#include <linux/slab.h>
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index e14f09e3a4b0..e311cc5df358 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Keyring handling
*
* Copyright (C) 2004-2005, 2008, 2013 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/export.h>
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 06df9d5e7572..085f907b64ac 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Key permission checking
*
* Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/export.h>
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index d0cb5b32eff7..da9a0f42b795 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* General persistent per-UID keyrings register
*
* Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
*/
#include <linux/user_namespace.h>
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 78ac305d715e..4e3266a2529e 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* procfs files for key database enumeration
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/init.h>
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 9320424c4a46..0b9406bf60e5 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Manage a process's keyrings
*
* Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/init.h>
@@ -58,7 +54,7 @@ int install_user_keyrings(void)
kenter("%p{%u}", user, uid);
- if (user->uid_keyring && user->session_keyring) {
+ if (READ_ONCE(user->uid_keyring) && READ_ONCE(user->session_keyring)) {
kleave(" = 0 [exist]");
return 0;
}
@@ -111,8 +107,10 @@ int install_user_keyrings(void)
}
/* install the keyrings */
- user->uid_keyring = uid_keyring;
- user->session_keyring = session_keyring;
+ /* paired with READ_ONCE() */
+ smp_store_release(&user->uid_keyring, uid_keyring);
+ /* paired with READ_ONCE() */
+ smp_store_release(&user->session_keyring, session_keyring);
}
mutex_unlock(&key_user_keyring_mutex);
@@ -227,6 +225,7 @@ static int install_process_keyring(void)
* Install the given keyring as the session keyring of the given credentials
* struct, replacing the existing one if any. If the given keyring is NULL,
* then install a new anonymous session keyring.
+ * @cred can not be in use by any task yet.
*
* Return: 0 on success; -errno on failure.
*/
@@ -254,7 +253,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
/* install the keyring */
old = cred->session_keyring;
- rcu_assign_pointer(cred->session_keyring, keyring);
+ cred->session_keyring = keyring;
if (old)
key_put(old);
@@ -339,6 +338,7 @@ void key_fsgid_changed(struct task_struct *tsk)
key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
{
key_ref_t key_ref, ret, err;
+ const struct cred *cred = ctx->cred;
/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
* searchable, but we failed to find a key or we found a negative key;
@@ -352,9 +352,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
err = ERR_PTR(-EAGAIN);
/* search the thread keyring first */
- if (ctx->cred->thread_keyring) {
+ if (cred->thread_keyring) {
key_ref = keyring_search_aux(
- make_key_ref(ctx->cred->thread_keyring, 1), ctx);
+ make_key_ref(cred->thread_keyring, 1), ctx);
if (!IS_ERR(key_ref))
goto found;
@@ -370,9 +370,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
}
/* search the process keyring second */
- if (ctx->cred->process_keyring) {
+ if (cred->process_keyring) {
key_ref = keyring_search_aux(
- make_key_ref(ctx->cred->process_keyring, 1), ctx);
+ make_key_ref(cred->process_keyring, 1), ctx);
if (!IS_ERR(key_ref))
goto found;
@@ -391,12 +391,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
}
/* search the session keyring */
- if (ctx->cred->session_keyring) {
- rcu_read_lock();
+ if (cred->session_keyring) {
key_ref = keyring_search_aux(
- make_key_ref(rcu_dereference(ctx->cred->session_keyring), 1),
- ctx);
- rcu_read_unlock();
+ make_key_ref(cred->session_keyring, 1), ctx);
if (!IS_ERR(key_ref))
goto found;
@@ -415,9 +412,9 @@ key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
}
}
/* or search the user-session keyring */
- else if (ctx->cred->user->session_keyring) {
+ else if (READ_ONCE(cred->user->session_keyring)) {
key_ref = keyring_search_aux(
- make_key_ref(ctx->cred->user->session_keyring, 1),
+ make_key_ref(READ_ONCE(cred->user->session_keyring), 1),
ctx);
if (!IS_ERR(key_ref))
goto found;
@@ -604,7 +601,7 @@ try_again:
goto error;
goto reget_creds;
} else if (ctx.cred->session_keyring ==
- ctx.cred->user->session_keyring &&
+ READ_ONCE(ctx.cred->user->session_keyring) &&
lflags & KEY_LOOKUP_CREATE) {
ret = join_session_keyring(NULL);
if (ret < 0)
@@ -612,15 +609,13 @@ try_again:
goto reget_creds;
}
- rcu_read_lock();
- key = rcu_dereference(ctx.cred->session_keyring);
+ key = ctx.cred->session_keyring;
__key_get(key);
- rcu_read_unlock();
key_ref = make_key_ref(key, 1);
break;
case KEY_SPEC_USER_KEYRING:
- if (!ctx.cred->user->uid_keyring) {
+ if (!READ_ONCE(ctx.cred->user->uid_keyring)) {
ret = install_user_keyrings();
if (ret < 0)
goto error;
@@ -632,7 +627,7 @@ try_again:
break;
case KEY_SPEC_USER_SESSION_KEYRING:
- if (!ctx.cred->user->session_keyring) {
+ if (!READ_ONCE(ctx.cred->user->session_keyring)) {
ret = install_user_keyrings();
if (ret < 0)
goto error;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 2f17d84d46f1..8ae3b7b18801 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Request a key from userspace
*
* Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
* See Documentation/security/keys/request-key.rst
*/
@@ -142,12 +138,10 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
prkey = cred->process_keyring->serial;
sprintf(keyring_str[1], "%d", prkey);
- rcu_read_lock();
- session = rcu_dereference(cred->session_keyring);
+ session = cred->session_keyring;
if (!session)
session = cred->user->session_keyring;
sskey = session->serial;
- rcu_read_unlock();
sprintf(keyring_str[2], "%d", sskey);
@@ -287,10 +281,7 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
/* fall through */
case KEY_REQKEY_DEFL_SESSION_KEYRING:
- rcu_read_lock();
- dest_keyring = key_get(
- rcu_dereference(cred->session_keyring));
- rcu_read_unlock();
+ dest_keyring = key_get(cred->session_keyring);
if (dest_keyring)
break;
@@ -298,11 +289,12 @@ static int construct_get_dest_keyring(struct key **_dest_keyring)
/* fall through */
case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
dest_keyring =
- key_get(cred->user->session_keyring);
+ key_get(READ_ONCE(cred->user->session_keyring));
break;
case KEY_REQKEY_DEFL_USER_KEYRING:
- dest_keyring = key_get(cred->user->uid_keyring);
+ dest_keyring =
+ key_get(READ_ONCE(cred->user->uid_keyring));
break;
case KEY_REQKEY_DEFL_GROUP_KEYRING:
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index bda6201c6c45..e45b5cf3b97f 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Request key authorisation token key definition.
*
* Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
* See Documentation/security/keys/request-key.rst
*/
diff --git a/security/keys/sysctl.c b/security/keys/sysctl.c
index b68faa1a5cfd..dd1e21fab827 100644
--- a/security/keys/sysctl.c
+++ b/security/keys/sysctl.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* Key management controls
*
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
*/
#include <linux/key.h>
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index efdbf17f3915..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;
}
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 5666fe0352f7..6f12de4ce549 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/* user_defined.c: user defined key type
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#include <linux/export.h>
diff --git a/security/loadpin/Kconfig b/security/loadpin/Kconfig
index a0d70d82b98e..91be65dec2ab 100644
--- a/security/loadpin/Kconfig
+++ b/security/loadpin/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_LOADPIN
bool "Pin load of kernel files (modules, fw, etc) to one filesystem"
depends on SECURITY && BLOCK
diff --git a/security/loadpin/Makefile b/security/loadpin/Makefile
index c2d77f83037b..0ead1c3105fd 100644
--- a/security/loadpin/Makefile
+++ b/security/loadpin/Makefile
@@ -1 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_SECURITY_LOADPIN) += loadpin.o
diff --git a/security/safesetid/Kconfig b/security/safesetid/Kconfig
index 4f415c4e3f93..18b5fb90417b 100644
--- a/security/safesetid/Kconfig
+++ b/security/safesetid/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_SAFESETID
bool "Gate setid transitions to limit CAP_SET{U/G}ID capabilities"
depends on SECURITY
diff --git a/security/security.c b/security/security.c
index 23cbb1a295a3..f493db0bf62a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Security plug functions
*
@@ -5,11 +6,6 @@
* Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
* Copyright (C) 2016 Mellanox Technologies
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
*/
#define pr_fmt(fmt) "LSM: " fmt
@@ -866,6 +862,11 @@ int security_add_mnt_opt(const char *option, const char *val, int len,
}
EXPORT_SYMBOL(security_add_mnt_opt);
+int security_move_mount(const struct path *from_path, const struct path *to_path)
+{
+ return call_int_hook(move_mount, 0, from_path, to_path);
+}
+
int security_inode_alloc(struct inode *inode)
{
int rc = lsm_inode_alloc(inode);
@@ -1318,6 +1319,12 @@ int security_inode_copy_up_xattr(const char *name)
}
EXPORT_SYMBOL(security_inode_copy_up_xattr);
+int security_kernfs_init_security(struct kernfs_node *kn_dir,
+ struct kernfs_node *kn)
+{
+ return call_int_hook(kernfs_init_security, 0, kn_dir, kn);
+}
+
int security_file_permission(struct file *file, int mask)
{
int ret;
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index 55f032f1fc2d..5711689deb6a 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_SELINUX
bool "NSA SELinux Support"
depends on SECURITY_NETWORK && AUDIT && NET && INET
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1d0b37af2444..3ec702cf46ca 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -89,6 +89,8 @@
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/bpf.h>
+#include <linux/kernfs.h>
+#include <linux/stringhash.h> /* for hashlen_string() */
#include <uapi/linux/mount.h>
#include "avc.h"
@@ -751,11 +753,13 @@ static int selinux_set_mnt_opts(struct super_block *sb,
if (!strcmp(sb->s_type->name, "debugfs") ||
!strcmp(sb->s_type->name, "tracefs") ||
- !strcmp(sb->s_type->name, "sysfs") ||
- !strcmp(sb->s_type->name, "pstore") ||
+ !strcmp(sb->s_type->name, "pstore"))
+ sbsec->flags |= SE_SBGENFS;
+
+ if (!strcmp(sb->s_type->name, "sysfs") ||
!strcmp(sb->s_type->name, "cgroup") ||
!strcmp(sb->s_type->name, "cgroup2"))
- sbsec->flags |= SE_SBGENFS;
+ sbsec->flags |= SE_SBGENFS | SE_SBGENFS_XATTR;
if (!sbsec->behavior) {
/*
@@ -1354,6 +1358,67 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
return rc;
}
+static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry,
+ u32 def_sid, u32 *sid)
+{
+#define INITCONTEXTLEN 255
+ char *context;
+ unsigned int len;
+ int rc;
+
+ len = INITCONTEXTLEN;
+ context = kmalloc(len + 1, GFP_NOFS);
+ if (!context)
+ return -ENOMEM;
+
+ context[len] = '\0';
+ rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
+ if (rc == -ERANGE) {
+ kfree(context);
+
+ /* Need a larger buffer. Query for the right size. */
+ rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
+ if (rc < 0)
+ return rc;
+
+ len = rc;
+ context = kmalloc(len + 1, GFP_NOFS);
+ if (!context)
+ return -ENOMEM;
+
+ context[len] = '\0';
+ rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX,
+ context, len);
+ }
+ if (rc < 0) {
+ kfree(context);
+ if (rc != -ENODATA) {
+ pr_warn("SELinux: %s: getxattr returned %d for dev=%s ino=%ld\n",
+ __func__, -rc, inode->i_sb->s_id, inode->i_ino);
+ return rc;
+ }
+ *sid = def_sid;
+ return 0;
+ }
+
+ rc = security_context_to_sid_default(&selinux_state, context, rc, sid,
+ def_sid, GFP_NOFS);
+ if (rc) {
+ char *dev = inode->i_sb->s_id;
+ unsigned long ino = inode->i_ino;
+
+ if (rc == -EINVAL) {
+ pr_notice_ratelimited("SELinux: inode=%lu on dev=%s was found to have an invalid context=%s. This indicates you may need to relabel the inode or the filesystem in question.\n",
+ ino, dev, context);
+ } else {
+ pr_warn("SELinux: %s: context_to_sid(%s) returned %d for dev=%s ino=%ld\n",
+ __func__, context, -rc, dev, ino);
+ }
+ }
+ kfree(context);
+ return 0;
+}
+
/* The inode's security attributes must be initialized before first use. */
static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry)
{
@@ -1362,9 +1427,6 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
u32 task_sid, sid = 0;
u16 sclass;
struct dentry *dentry;
-#define INITCONTEXTLEN 255
- char *context = NULL;
- unsigned len = 0;
int rc = 0;
if (isec->initialized == LABEL_INITIALIZED)
@@ -1432,72 +1494,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
goto out;
}
- len = INITCONTEXTLEN;
- context = kmalloc(len+1, GFP_NOFS);
- if (!context) {
- rc = -ENOMEM;
- dput(dentry);
- goto out;
- }
- context[len] = '\0';
- rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
- if (rc == -ERANGE) {
- kfree(context);
-
- /* Need a larger buffer. Query for the right size. */
- rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0);
- if (rc < 0) {
- dput(dentry);
- goto out;
- }
- len = rc;
- context = kmalloc(len+1, GFP_NOFS);
- if (!context) {
- rc = -ENOMEM;
- dput(dentry);
- goto out;
- }
- context[len] = '\0';
- rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len);
- }
+ rc = inode_doinit_use_xattr(inode, dentry, sbsec->def_sid,
+ &sid);
dput(dentry);
- if (rc < 0) {
- if (rc != -ENODATA) {
- pr_warn("SELinux: %s: getxattr returned "
- "%d for dev=%s ino=%ld\n", __func__,
- -rc, inode->i_sb->s_id, inode->i_ino);
- kfree(context);
- goto out;
- }
- /* Map ENODATA to the default file SID */
- sid = sbsec->def_sid;
- rc = 0;
- } else {
- rc = security_context_to_sid_default(&selinux_state,
- context, rc, &sid,
- sbsec->def_sid,
- GFP_NOFS);
- if (rc) {
- char *dev = inode->i_sb->s_id;
- unsigned long ino = inode->i_ino;
-
- if (rc == -EINVAL) {
- if (printk_ratelimit())
- pr_notice("SELinux: inode=%lu on dev=%s was found to have an invalid "
- "context=%s. This indicates you may need to relabel the inode or the "
- "filesystem in question.\n", ino, dev, context);
- } else {
- pr_warn("SELinux: %s: context_to_sid(%s) "
- "returned %d for dev=%s ino=%ld\n",
- __func__, context, -rc, dev, ino);
- }
- kfree(context);
- /* Leave with the unlabeled SID */
- rc = 0;
- break;
- }
- }
- kfree(context);
+ if (rc)
+ goto out;
break;
case SECURITY_FS_USE_TASK:
sid = task_sid;
@@ -1548,9 +1549,21 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
goto out;
rc = selinux_genfs_get_sid(dentry, sclass,
sbsec->flags, &sid);
- dput(dentry);
- if (rc)
+ if (rc) {
+ dput(dentry);
goto out;
+ }
+
+ if ((sbsec->flags & SE_SBGENFS_XATTR) &&
+ (inode->i_opflags & IOP_XATTR)) {
+ rc = inode_doinit_use_xattr(inode, dentry,
+ sid, &sid);
+ if (rc) {
+ dput(dentry);
+ goto out;
+ }
+ }
+ dput(dentry);
}
break;
}
@@ -3371,6 +3384,67 @@ static int selinux_inode_copy_up_xattr(const char *name)
return -EOPNOTSUPP;
}
+/* kernfs node operations */
+
+static int selinux_kernfs_init_security(struct kernfs_node *kn_dir,
+ struct kernfs_node *kn)
+{
+ const struct task_security_struct *tsec = current_security();
+ u32 parent_sid, newsid, clen;
+ int rc;
+ char *context;
+
+ rc = kernfs_xattr_get(kn_dir, XATTR_NAME_SELINUX, NULL, 0);
+ if (rc == -ENODATA)
+ return 0;
+ else if (rc < 0)
+ return rc;
+
+ clen = (u32)rc;
+ context = kmalloc(clen, GFP_KERNEL);
+ if (!context)
+ return -ENOMEM;
+
+ rc = kernfs_xattr_get(kn_dir, XATTR_NAME_SELINUX, context, clen);
+ if (rc < 0) {
+ kfree(context);
+ return rc;
+ }
+
+ rc = security_context_to_sid(&selinux_state, context, clen, &parent_sid,
+ GFP_KERNEL);
+ kfree(context);
+ if (rc)
+ return rc;
+
+ if (tsec->create_sid) {
+ newsid = tsec->create_sid;
+ } else {
+ u16 secclass = inode_mode_to_security_class(kn->mode);
+ struct qstr q;
+
+ q.name = kn->name;
+ q.hash_len = hashlen_string(kn_dir, kn->name);
+
+ rc = security_transition_sid(&selinux_state, tsec->sid,
+ parent_sid, secclass, &q,
+ &newsid);
+ if (rc)
+ return rc;
+ }
+
+ rc = security_sid_to_context_force(&selinux_state, newsid,
+ &context, &clen);
+ if (rc)
+ return rc;
+
+ rc = kernfs_xattr_set(kn, XATTR_NAME_SELINUX, context, clen,
+ XATTR_CREATE);
+ kfree(context);
+ return rc;
+}
+
+
/* file security operations */
static int selinux_revalidate_file_permission(struct file *file, int mask)
@@ -4438,7 +4512,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
struct lsm_network_audit net = {0,};
struct sockaddr_in *addr4 = NULL;
struct sockaddr_in6 *addr6 = NULL;
- u16 family_sa = address->sa_family;
+ u16 family_sa;
unsigned short snum;
u32 sid, node_perm;
@@ -4448,6 +4522,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
* need to check address->sa_family as it is possible to have
* sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
*/
+ if (addrlen < offsetofend(struct sockaddr, sa_family))
+ return -EINVAL;
+ family_sa = address->sa_family;
switch (family_sa) {
case AF_UNSPEC:
case AF_INET:
@@ -4560,6 +4637,14 @@ static int selinux_socket_connect_helper(struct socket *sock,
err = sock_has_perm(sk, SOCKET__CONNECT);
if (err)
return err;
+ if (addrlen < offsetofend(struct sockaddr, sa_family))
+ return -EINVAL;
+
+ /* connect(AF_UNSPEC) has special handling, as it is a documented
+ * way to disconnect the socket
+ */
+ if (address->sa_family == AF_UNSPEC)
+ return 0;
/*
* If a TCP, DCCP or SCTP socket, check name_connect permission
@@ -6719,6 +6804,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up),
LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr),
+ LSM_HOOK_INIT(kernfs_init_security, selinux_kernfs_init_security),
+
LSM_HOOK_INIT(file_permission, selinux_file_permission),
LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
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"
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index 8671de09c363..d30d8d7cdc9c 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -1,26 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* SELinux interface to the NetLabel subsystem
*
* Author: Paul Moore <paul@paul-moore.com>
- *
*/
/*
* (c) Copyright Hewlett-Packard Development Company, L.P., 2006
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#ifndef _SELINUX_NETLABEL_H_
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index b5b7c5aade8c..111121281c47 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -58,6 +58,7 @@
#define SE_SBINITIALIZED 0x0100
#define SE_SBPROC 0x0200
#define SE_SBGENFS 0x0400
+#define SE_SBGENFS_XATTR 0x0800
#define CONTEXT_STR "context"
#define FSCONTEXT_STR "fscontext"
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 186e727b737b..abaab7683840 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* SELinux NetLabel Support
*
@@ -5,25 +6,10 @@
* subsystem.
*
* Author: Paul Moore <paul@paul-moore.com>
- *
*/
/*
* (c) Copyright Hewlett-Packard Development Company, L.P., 2007, 2008
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#include <linux/spinlock.h>
@@ -288,11 +274,8 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
int rc;
struct netlbl_lsm_secattr secattr;
struct sk_security_struct *sksec = ep->base.sk->sk_security;
- struct sockaddr *addr;
struct sockaddr_in addr4;
-#if IS_ENABLED(CONFIG_IPV6)
struct sockaddr_in6 addr6;
-#endif
if (ep->base.sk->sk_family != PF_INET &&
ep->base.sk->sk_family != PF_INET6)
@@ -310,16 +293,15 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep,
if (ip_hdr(skb)->version == 4) {
addr4.sin_family = AF_INET;
addr4.sin_addr.s_addr = ip_hdr(skb)->saddr;
- addr = (struct sockaddr *)&addr4;
-#if IS_ENABLED(CONFIG_IPV6)
- } else {
+ rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr4, &secattr);
+ } else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) {
addr6.sin6_family = AF_INET6;
addr6.sin6_addr = ipv6_hdr(skb)->saddr;
- addr = (struct sockaddr *)&addr6;
-#endif
+ rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr6, &secattr);
+ } else {
+ rc = -EAFNOSUPPORT;
}
- rc = netlbl_conn_setattr(ep->base.sk, addr, &secattr);
if (rc == 0)
sksec->nlbl_state = NLBL_LABELED;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ec62918521b1..cc043bc8fd4c 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1318,14 +1318,11 @@ static int security_sid_to_context_core(struct selinux_state *state,
rc = -EINVAL;
goto out_unlock;
}
- if (only_invalid && !context->len) {
- scontext = NULL;
- scontext_len = 0;
+ if (only_invalid && !context->len)
rc = 0;
- } else {
+ else
rc = context_struct_to_string(policydb, context, scontext,
scontext_len);
- }
out_unlock:
read_unlock(&state->ss->policy_rwlock);
out:
diff --git a/security/smack/Kconfig b/security/smack/Kconfig
index 923b120e0fa5..5a8dfad469c3 100644
--- a/security/smack/Kconfig
+++ b/security/smack/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_SMACK
bool "Simplified Mandatory Access Control Kernel Support"
depends on NET
diff --git a/security/smack/Makefile b/security/smack/Makefile
index ee2ebd504541..6dbf6e22a68b 100644
--- a/security/smack/Makefile
+++ b/security/smack/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the SMACK LSM
#
diff --git a/security/smack/smack.h b/security/smack/smack.h
index cf52af77d15e..e41ca1d58484 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -348,6 +348,7 @@ extern struct list_head smack_onlycap_list;
#define SMACK_HASH_SLOTS 16
extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
+extern struct kmem_cache *smack_rule_cache;
static inline struct task_smack *smack_cred(const struct cred *cred)
{
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 5c1613519d5a..0de725f88bed 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -59,6 +59,7 @@ DEFINE_MUTEX(smack_ipv6_lock);
static LIST_HEAD(smk_ipv6_port_list);
#endif
static struct kmem_cache *smack_inode_cache;
+struct kmem_cache *smack_rule_cache;
int smack_enabled;
#define A(s) {"smack"#s, sizeof("smack"#s) - 1, Opt_##s}
@@ -354,7 +355,7 @@ static int smk_copy_rules(struct list_head *nhead, struct list_head *ohead,
int rc = 0;
list_for_each_entry_rcu(orp, ohead, list) {
- nrp = kzalloc(sizeof(struct smack_rule), gfp);
+ nrp = kmem_cache_zalloc(smack_rule_cache, gfp);
if (nrp == NULL) {
rc = -ENOMEM;
break;
@@ -1931,7 +1932,7 @@ static void smack_cred_free(struct cred *cred)
list_for_each_safe(l, n, &tsp->smk_rules) {
rp = list_entry(l, struct smack_rule, list);
list_del(&rp->list);
- kfree(rp);
+ kmem_cache_free(smack_rule_cache, rp);
}
}
@@ -2805,13 +2806,17 @@ static int smack_socket_socketpair(struct socket *socka,
*
* Records the label bound to a port.
*
- * Returns 0
+ * Returns 0 on success, and error code otherwise
*/
static int smack_socket_bind(struct socket *sock, struct sockaddr *address,
int addrlen)
{
- if (sock->sk != NULL && sock->sk->sk_family == PF_INET6)
+ if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) {
+ if (addrlen < SIN6_LEN_RFC2133 ||
+ address->sa_family != AF_INET6)
+ return -EINVAL;
smk_ipv6_port_label(sock, address);
+ }
return 0;
}
#endif /* SMACK_IPV6_PORT_LABELING */
@@ -2847,12 +2852,13 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
switch (sock->sk->sk_family) {
case PF_INET:
- if (addrlen < sizeof(struct sockaddr_in))
+ if (addrlen < sizeof(struct sockaddr_in) ||
+ sap->sa_family != AF_INET)
return -EINVAL;
rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
break;
case PF_INET6:
- if (addrlen < sizeof(struct sockaddr_in6))
+ if (addrlen < SIN6_LEN_RFC2133 || sap->sa_family != AF_INET6)
return -EINVAL;
#ifdef SMACK_IPV6_SECMARK_LABELING
rsp = smack_ipv6host_label(sip);
@@ -3682,9 +3688,16 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
switch (sock->sk->sk_family) {
case AF_INET:
+ if (msg->msg_namelen < sizeof(struct sockaddr_in) ||
+ sip->sin_family != AF_INET)
+ return -EINVAL;
rc = smack_netlabel_send(sock->sk, sip);
break;
+#if IS_ENABLED(CONFIG_IPV6)
case AF_INET6:
+ if (msg->msg_namelen < SIN6_LEN_RFC2133 ||
+ sap->sin6_family != AF_INET6)
+ return -EINVAL;
#ifdef SMACK_IPV6_SECMARK_LABELING
rsp = smack_ipv6host_label(sap);
if (rsp != NULL)
@@ -3694,6 +3707,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg,
#ifdef SMACK_IPV6_PORT_LABELING
rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING);
#endif
+#endif /* IS_ENABLED(CONFIG_IPV6) */
break;
}
return rc;
@@ -3906,6 +3920,8 @@ access_check:
#ifdef SMACK_IPV6_SECMARK_LABELING
if (skb && skb->secmark != 0)
skp = smack_from_secid(skb->secmark);
+ else if (smk_ipv6_localhost(&sadd))
+ break;
else
skp = smack_ipv6host_label(&sadd);
if (skp == NULL)
@@ -4758,6 +4774,12 @@ static __init int smack_init(void)
if (!smack_inode_cache)
return -ENOMEM;
+ smack_rule_cache = KMEM_CACHE(smack_rule, 0);
+ if (!smack_rule_cache) {
+ kmem_cache_destroy(smack_inode_cache);
+ return -ENOMEM;
+ }
+
/*
* Set the security state for the initial task.
*/
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index faf2ea3968b3..47f73a0dabb1 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -67,7 +67,6 @@ enum smk_inos {
/*
* List locks
*/
-static DEFINE_MUTEX(smack_master_list_lock);
static DEFINE_MUTEX(smack_cipso_lock);
static DEFINE_MUTEX(smack_ambient_lock);
static DEFINE_MUTEX(smk_net4addr_lock);
@@ -134,15 +133,7 @@ LIST_HEAD(smk_net6addr_list);
/*
* Rule lists are maintained for each label.
- * This master list is just for reading /smack/load and /smack/load2.
*/
-struct smack_master_list {
- struct list_head list;
- struct smack_rule *smk_rule;
-};
-
-static LIST_HEAD(smack_rule_list);
-
struct smack_parsed_rule {
struct smack_known *smk_subject;
struct smack_known *smk_object;
@@ -211,7 +202,6 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
* @srp: the rule to add or replace
* @rule_list: the list of rules
* @rule_lock: the rule list lock
- * @global: if non-zero, indicates a global rule
*
* Looks through the current subject/object/access list for
* the subject/object pair and replaces the access that was
@@ -223,10 +213,9 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap)
*/
static int smk_set_access(struct smack_parsed_rule *srp,
struct list_head *rule_list,
- struct mutex *rule_lock, int global)
+ struct mutex *rule_lock)
{
struct smack_rule *sp;
- struct smack_master_list *smlp;
int found = 0;
int rc = 0;
@@ -247,7 +236,7 @@ static int smk_set_access(struct smack_parsed_rule *srp,
}
if (found == 0) {
- sp = kzalloc(sizeof(*sp), GFP_KERNEL);
+ sp = kmem_cache_zalloc(smack_rule_cache, GFP_KERNEL);
if (sp == NULL) {
rc = -ENOMEM;
goto out;
@@ -258,22 +247,6 @@ static int smk_set_access(struct smack_parsed_rule *srp,
sp->smk_access = srp->smk_access1 & ~srp->smk_access2;
list_add_rcu(&sp->list, rule_list);
- /*
- * If this is a global as opposed to self and a new rule
- * it needs to get added for reporting.
- */
- if (global) {
- mutex_unlock(rule_lock);
- smlp = kzalloc(sizeof(*smlp), GFP_KERNEL);
- if (smlp != NULL) {
- smlp->smk_rule = sp;
- mutex_lock(&smack_master_list_lock);
- list_add_rcu(&smlp->list, &smack_rule_list);
- mutex_unlock(&smack_master_list_lock);
- } else
- rc = -ENOMEM;
- return rc;
- }
}
out:
@@ -540,9 +513,9 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
if (rule_list == NULL)
rc = smk_set_access(&rule, &rule.smk_subject->smk_rules,
- &rule.smk_subject->smk_rules_lock, 1);
+ &rule.smk_subject->smk_rules_lock);
else
- rc = smk_set_access(&rule, rule_list, rule_lock, 0);
+ rc = smk_set_access(&rule, rule_list, rule_lock);
if (rc)
goto out;
@@ -636,21 +609,23 @@ static void smk_rule_show(struct seq_file *s, struct smack_rule *srp, int max)
static void *load2_seq_start(struct seq_file *s, loff_t *pos)
{
- return smk_seq_start(s, pos, &smack_rule_list);
+ return smk_seq_start(s, pos, &smack_known_list);
}
static void *load2_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
- return smk_seq_next(s, v, pos, &smack_rule_list);
+ return smk_seq_next(s, v, pos, &smack_known_list);
}
static int load_seq_show(struct seq_file *s, void *v)
{
struct list_head *list = v;
- struct smack_master_list *smlp =
- list_entry_rcu(list, struct smack_master_list, list);
+ struct smack_rule *srp;
+ struct smack_known *skp =
+ list_entry_rcu(list, struct smack_known, list);
- smk_rule_show(s, smlp->smk_rule, SMK_LABELLEN);
+ list_for_each_entry_rcu(srp, &skp->smk_rules, list)
+ smk_rule_show(s, srp, SMK_LABELLEN);
return 0;
}
@@ -2352,10 +2327,12 @@ static const struct file_operations smk_access_ops = {
static int load2_seq_show(struct seq_file *s, void *v)
{
struct list_head *list = v;
- struct smack_master_list *smlp =
- list_entry_rcu(list, struct smack_master_list, list);
+ struct smack_rule *srp;
+ struct smack_known *skp =
+ list_entry_rcu(list, struct smack_known, list);
- smk_rule_show(s, smlp->smk_rule, SMK_LONGLABEL);
+ list_for_each_entry_rcu(srp, &skp->smk_rules, list)
+ smk_rule_show(s, srp, SMK_LONGLABEL);
return 0;
}
diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig
index 404dce66952a..9221ea506631 100644
--- a/security/tomoyo/Kconfig
+++ b/security/tomoyo/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_TOMOYO
bool "TOMOYO Linux Support"
depends on SECURITY
@@ -74,3 +75,13 @@ config SECURITY_TOMOYO_ACTIVATION_TRIGGER
You can override this setting via TOMOYO_trigger= kernel command line
option. For example, if you pass init=/bin/systemd option, you may
want to also pass TOMOYO_trigger=/bin/systemd option.
+
+config SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING
+ bool "Use insecure built-in settings for fuzzing tests."
+ default n
+ depends on SECURITY_TOMOYO
+ select SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
+ help
+ Enabling this option forces minimal built-in policy and disables
+ domain/program checks for run-time policy modifications. Please enable
+ this option only if this kernel is built for doing fuzzing tests.
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 57988d95d33d..dd3d5942e669 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -940,7 +940,7 @@ static bool tomoyo_manager(void)
const char *exe;
const struct task_struct *task = current;
const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname;
- bool found = false;
+ bool found = IS_ENABLED(CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING);
if (!tomoyo_policy_loaded)
return true;
@@ -2810,6 +2810,16 @@ void tomoyo_check_profile(void)
*/
void __init tomoyo_load_builtin_policy(void)
{
+#ifdef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING
+ static char tomoyo_builtin_profile[] __initdata =
+ "PROFILE_VERSION=20150505\n"
+ "0-CONFIG={ mode=learning grant_log=no reject_log=yes }\n";
+ static char tomoyo_builtin_exception_policy[] __initdata =
+ "aggregator proc:/self/exe /proc/self/exe\n";
+ static char tomoyo_builtin_domain_policy[] __initdata = "";
+ static char tomoyo_builtin_manager[] __initdata = "";
+ static char tomoyo_builtin_stat[] __initdata = "";
+#else
/*
* This include file is manually created and contains built-in policy
* named "tomoyo_builtin_profile", "tomoyo_builtin_exception_policy",
@@ -2817,6 +2827,7 @@ void __init tomoyo_load_builtin_policy(void)
* "tomoyo_builtin_stat" in the form of "static char [] __initdata".
*/
#include "builtin-policy.h"
+#endif
u8 i;
const int idx = tomoyo_read_lock();
diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c
index 9094f4b3b367..f9ff121d7e1e 100644
--- a/security/tomoyo/network.c
+++ b/security/tomoyo/network.c
@@ -505,6 +505,8 @@ static int tomoyo_check_inet_address(const struct sockaddr *addr,
{
struct tomoyo_inet_addr_info *i = &address->inet;
+ if (addr_len < offsetofend(struct sockaddr, sa_family))
+ return 0;
switch (addr->sa_family) {
case AF_INET6:
if (addr_len < SIN6_LEN_RFC2133)
@@ -594,6 +596,8 @@ static int tomoyo_check_unix_address(struct sockaddr *addr,
{
struct tomoyo_unix_addr_info *u = &address->unix0;
+ if (addr_len < offsetofend(struct sockaddr, sa_family))
+ return 0;
if (addr->sa_family != AF_UNIX)
return 0;
u->addr = ((struct sockaddr_un *) addr)->sun_path;
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 85e6e31dd1e5..e7832448d721 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -295,7 +295,8 @@ char *tomoyo_realpath_from_path(const struct path *path)
* or dentry without vfsmount.
*/
if (!path->mnt ||
- (!inode->i_op->rename))
+ (!inode->i_op->rename &&
+ !(sb->s_type->fs_flags & FS_REQUIRES_DEV)))
pos = tomoyo_get_local_path(path->dentry, buf,
buf_len - 1);
/* Get absolute name for the rest. */
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 0517cbdd7275..52752e1a84ed 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -1076,8 +1076,10 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
domain->flags[TOMOYO_DIF_QUOTA_WARNED] = true;
/* r->granted = false; */
tomoyo_write_log(r, "%s", tomoyo_dif[TOMOYO_DIF_QUOTA_WARNED]);
+#ifndef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING
pr_warn("WARNING: Domain '%s' has too many ACLs to hold. Stopped learning mode.\n",
domain->domainname->name);
+#endif
}
return false;
}
diff --git a/security/yama/Kconfig b/security/yama/Kconfig
index 96b27405558a..a810304123ca 100644
--- a/security/yama/Kconfig
+++ b/security/yama/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
config SECURITY_YAMA
bool "Yama support"
depends on SECURITY
diff --git a/security/yama/Makefile b/security/yama/Makefile
index 8b5e06588456..0fa5d0fe2cf6 100644
--- a/security/yama/Makefile
+++ b/security/yama/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_SECURITY_YAMA) := yama.o
yama-y := yama_lsm.o