summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-28 11:14:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-28 11:14:15 -0400
commitaefcf2f4b58155d27340ba5f9ddbe9513da8286d (patch)
treea8ae994ca71b2e43e3075c796165e5ed62e28e42
parentf1f2f614d535564992f32e720739cb53cf03489f (diff)
parent45893a0abee6b5fd52994a3a1095735aeaec472b (diff)
Merge branch 'next-lockdown' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull kernel lockdown mode from James Morris: "This is the latest iteration of the kernel lockdown patchset, from Matthew Garrett, David Howells and others. From the original description: This patchset introduces an optional kernel lockdown feature, intended to strengthen the boundary between UID 0 and the kernel. When enabled, various pieces of kernel functionality are restricted. Applications that rely on low-level access to either hardware or the kernel may cease working as a result - therefore this should not be enabled without appropriate evaluation beforehand. The majority of mainstream distributions have been carrying variants of this patchset for many years now, so there's value in providing a doesn't meet every distribution requirement, but gets us much closer to not requiring external patches. There are two major changes since this was last proposed for mainline: - Separating lockdown from EFI secure boot. Background discussion is covered here: https://lwn.net/Articles/751061/ - Implementation as an LSM, with a default stackable lockdown LSM module. This allows the lockdown feature to be policy-driven, rather than encoding an implicit policy within the mechanism. The new locked_down LSM hook is provided to allow LSMs to make a policy decision around whether kernel functionality that would allow tampering with or examining the runtime state of the kernel should be permitted. The included lockdown LSM provides an implementation with a simple policy intended for general purpose use. This policy provides a coarse level of granularity, controllable via the kernel command line: lockdown={integrity|confidentiality} Enable the kernel lockdown feature. If set to integrity, kernel features that allow userland to modify the running kernel are disabled. If set to confidentiality, kernel features that allow userland to extract confidential information from the kernel are also disabled. This may also be controlled via /sys/kernel/security/lockdown and overriden by kernel configuration. New or existing LSMs may implement finer-grained controls of the lockdown features. Refer to the lockdown_reason documentation in include/linux/security.h for details. The lockdown feature has had signficant design feedback and review across many subsystems. This code has been in linux-next for some weeks, with a few fixes applied along the way. Stephen Rothwell noted that commit 9d1f8be5cf42 ("bpf: Restrict bpf when kernel lockdown is in confidentiality mode") is missing a Signed-off-by from its author. Matthew responded that he is providing this under category (c) of the DCO" * 'next-lockdown' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (31 commits) kexec: Fix file verification on S390 security: constify some arrays in lockdown LSM lockdown: Print current->comm in restriction messages efi: Restrict efivar_ssdt_load when the kernel is locked down tracefs: Restrict tracefs when the kernel is locked down debugfs: Restrict debugfs when the kernel is locked down kexec: Allow kexec_file() with appropriate IMA policy when locked down lockdown: Lock down perf when in confidentiality mode bpf: Restrict bpf when kernel lockdown is in confidentiality mode lockdown: Lock down tracing and perf kprobes when in confidentiality mode lockdown: Lock down /proc/kcore x86/mmiotrace: Lock down the testmmiotrace module lockdown: Lock down module params that specify hardware parameters (eg. ioport) lockdown: Lock down TIOCSSERIAL lockdown: Prohibit PCMCIA CIS storage when the kernel is locked down acpi: Disable ACPI table override if the kernel is locked down acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down ACPI: Limit access to custom_method when the kernel is locked down x86/msr: Restrict MSR access when the kernel is locked down x86: Lock down IO port access when the kernel is locked down ...
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt9
-rw-r--r--arch/arm64/Kconfig6
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/s390/kernel/kexec_elf.c4
-rw-r--r--arch/s390/kernel/kexec_image.c4
-rw-r--r--arch/s390/kernel/machine_kexec_file.c4
-rw-r--r--arch/x86/Kconfig20
-rw-r--r--arch/x86/boot/compressed/acpi.c19
-rw-r--r--arch/x86/include/asm/acpi.h9
-rw-r--r--arch/x86/include/asm/x86_init.h2
-rw-r--r--arch/x86/kernel/acpi/boot.c5
-rw-r--r--arch/x86/kernel/ima_arch.c4
-rw-r--r--arch/x86/kernel/ioport.c7
-rw-r--r--arch/x86/kernel/kexec-bzimage64.c1
-rw-r--r--arch/x86/kernel/msr.c8
-rw-r--r--arch/x86/kernel/x86_init.c1
-rw-r--r--arch/x86/mm/testmmiotrace.c5
-rw-r--r--crypto/asymmetric_keys/verify_pefile.c4
-rw-r--r--drivers/acpi/custom_method.c6
-rw-r--r--drivers/acpi/osl.c14
-rw-r--r--drivers/acpi/tables.c6
-rw-r--r--drivers/char/mem.c7
-rw-r--r--drivers/firmware/efi/efi.c6
-rw-r--r--drivers/pci/pci-sysfs.c16
-rw-r--r--drivers/pci/proc.c14
-rw-r--r--drivers/pci/syscall.c4
-rw-r--r--drivers/pcmcia/cistpl.c5
-rw-r--r--drivers/tty/serial/serial_core.c5
-rw-r--r--fs/debugfs/file.c30
-rw-r--r--fs/debugfs/inode.c32
-rw-r--r--fs/proc/kcore.c6
-rw-r--r--fs/tracefs/inode.c42
-rw-r--r--include/asm-generic/vmlinux.lds.h8
-rw-r--r--include/linux/acpi.h6
-rw-r--r--include/linux/ima.h9
-rw-r--r--include/linux/kexec.h4
-rw-r--r--include/linux/lsm_hooks.h13
-rw-r--r--include/linux/security.h59
-rw-r--r--init/Kconfig5
-rw-r--r--init/main.c1
-rw-r--r--kernel/events/core.c7
-rw-r--r--kernel/kexec.c8
-rw-r--r--kernel/kexec_file.c68
-rw-r--r--kernel/module.c37
-rw-r--r--kernel/params.c21
-rw-r--r--kernel/power/hibernate.c3
-rw-r--r--kernel/trace/bpf_trace.c10
-rw-r--r--kernel/trace/trace_kprobe.c5
-rw-r--r--security/Kconfig11
-rw-r--r--security/Makefile2
-rw-r--r--security/integrity/ima/Kconfig2
-rw-r--r--security/integrity/ima/ima.h2
-rw-r--r--security/integrity/ima/ima_main.c4
-rw-r--r--security/integrity/ima/ima_policy.c50
-rw-r--r--security/lockdown/Kconfig47
-rw-r--r--security/lockdown/Makefile1
-rw-r--r--security/lockdown/lockdown.c191
-rw-r--r--security/security.c56
58 files changed, 861 insertions, 76 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 944e03e29f65..c7ac2f3ac99f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2276,6 +2276,15 @@
2276 lockd.nlm_udpport=M [NFS] Assign UDP port. 2276 lockd.nlm_udpport=M [NFS] Assign UDP port.
2277 Format: <integer> 2277 Format: <integer>
2278 2278
2279 lockdown= [SECURITY]
2280 { integrity | confidentiality }
2281 Enable the kernel lockdown feature. If set to
2282 integrity, kernel features that allow userland to
2283 modify the running kernel are disabled. If set to
2284 confidentiality, kernel features that allow userland
2285 to extract confidential information from the kernel
2286 are also disabled.
2287
2279 locktorture.nreaders_stress= [KNL] 2288 locktorture.nreaders_stress= [KNL]
2280 Set the number of locking read-acquisition kthreads. 2289 Set the number of locking read-acquisition kthreads.
2281 Defaults to being automatically set based on the 2290 Defaults to being automatically set based on the
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 866e05882799..41a9b4257b72 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -982,7 +982,7 @@ config KEXEC_FILE
982 for kernel and initramfs as opposed to list of segments as 982 for kernel and initramfs as opposed to list of segments as
983 accepted by previous system call. 983 accepted by previous system call.
984 984
985config KEXEC_VERIFY_SIG 985config KEXEC_SIG
986 bool "Verify kernel signature during kexec_file_load() syscall" 986 bool "Verify kernel signature during kexec_file_load() syscall"
987 depends on KEXEC_FILE 987 depends on KEXEC_FILE
988 help 988 help
@@ -997,13 +997,13 @@ config KEXEC_VERIFY_SIG
997config KEXEC_IMAGE_VERIFY_SIG 997config KEXEC_IMAGE_VERIFY_SIG
998 bool "Enable Image signature verification support" 998 bool "Enable Image signature verification support"
999 default y 999 default y
1000 depends on KEXEC_VERIFY_SIG 1000 depends on KEXEC_SIG
1001 depends on EFI && SIGNED_PE_FILE_VERIFICATION 1001 depends on EFI && SIGNED_PE_FILE_VERIFICATION
1002 help 1002 help
1003 Enable Image signature verification support. 1003 Enable Image signature verification support.
1004 1004
1005comment "Support for PE file signature verification disabled" 1005comment "Support for PE file signature verification disabled"
1006 depends on KEXEC_VERIFY_SIG 1006 depends on KEXEC_SIG
1007 depends on !EFI || !SIGNED_PE_FILE_VERIFICATION 1007 depends on !EFI || !SIGNED_PE_FILE_VERIFICATION
1008 1008
1009config CRASH_DUMP 1009config CRASH_DUMP
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 68f7c2b16ff7..43a81d0ad507 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -554,7 +554,7 @@ config ARCH_HAS_KEXEC_PURGATORY
554 def_bool y 554 def_bool y
555 depends on KEXEC_FILE 555 depends on KEXEC_FILE
556 556
557config KEXEC_VERIFY_SIG 557config KEXEC_SIG
558 bool "Verify kernel signature during kexec_file_load() syscall" 558 bool "Verify kernel signature during kexec_file_load() syscall"
559 depends on KEXEC_FILE && MODULE_SIG_FORMAT 559 depends on KEXEC_FILE && MODULE_SIG_FORMAT
560 help 560 help
diff --git a/arch/s390/kernel/kexec_elf.c b/arch/s390/kernel/kexec_elf.c
index 6d0635ceddd0..9da6fa30c447 100644
--- a/arch/s390/kernel/kexec_elf.c
+++ b/arch/s390/kernel/kexec_elf.c
@@ -130,7 +130,7 @@ static int s390_elf_probe(const char *buf, unsigned long len)
130const struct kexec_file_ops s390_kexec_elf_ops = { 130const struct kexec_file_ops s390_kexec_elf_ops = {
131 .probe = s390_elf_probe, 131 .probe = s390_elf_probe,
132 .load = s390_elf_load, 132 .load = s390_elf_load,
133#ifdef CONFIG_KEXEC_VERIFY_SIG 133#ifdef CONFIG_KEXEC_SIG
134 .verify_sig = s390_verify_sig, 134 .verify_sig = s390_verify_sig,
135#endif /* CONFIG_KEXEC_VERIFY_SIG */ 135#endif /* CONFIG_KEXEC_SIG */
136}; 136};
diff --git a/arch/s390/kernel/kexec_image.c b/arch/s390/kernel/kexec_image.c
index 58318bf89fd9..af23eff5774d 100644
--- a/arch/s390/kernel/kexec_image.c
+++ b/arch/s390/kernel/kexec_image.c
@@ -59,7 +59,7 @@ static int s390_image_probe(const char *buf, unsigned long len)
59const struct kexec_file_ops s390_kexec_image_ops = { 59const struct kexec_file_ops s390_kexec_image_ops = {
60 .probe = s390_image_probe, 60 .probe = s390_image_probe,
61 .load = s390_image_load, 61 .load = s390_image_load,
62#ifdef CONFIG_KEXEC_VERIFY_SIG 62#ifdef CONFIG_KEXEC_SIG
63 .verify_sig = s390_verify_sig, 63 .verify_sig = s390_verify_sig,
64#endif /* CONFIG_KEXEC_VERIFY_SIG */ 64#endif /* CONFIG_KEXEC_SIG */
65}; 65};
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
index 1ac9fbc6e01e..8415ae7d2a23 100644
--- a/arch/s390/kernel/machine_kexec_file.c
+++ b/arch/s390/kernel/machine_kexec_file.c
@@ -22,7 +22,7 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
22 NULL, 22 NULL,
23}; 23};
24 24
25#ifdef CONFIG_KEXEC_VERIFY_SIG 25#ifdef CONFIG_KEXEC_SIG
26int s390_verify_sig(const char *kernel, unsigned long kernel_len) 26int s390_verify_sig(const char *kernel, unsigned long kernel_len)
27{ 27{
28 const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; 28 const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1;
@@ -68,7 +68,7 @@ int s390_verify_sig(const char *kernel, unsigned long kernel_len)
68 VERIFYING_MODULE_SIGNATURE, 68 VERIFYING_MODULE_SIGNATURE,
69 NULL, NULL); 69 NULL, NULL);
70} 70}
71#endif /* CONFIG_KEXEC_VERIFY_SIG */ 71#endif /* CONFIG_KEXEC_SIG */
72 72
73static int kexec_file_update_purgatory(struct kimage *image, 73static int kexec_file_update_purgatory(struct kimage *image,
74 struct s390_load_data *data) 74 struct s390_load_data *data)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 37ed5f5910d5..d6e1faa28c58 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2031,20 +2031,30 @@ config KEXEC_FILE
2031config ARCH_HAS_KEXEC_PURGATORY 2031config ARCH_HAS_KEXEC_PURGATORY
2032 def_bool KEXEC_FILE 2032 def_bool KEXEC_FILE
2033 2033
2034config KEXEC_VERIFY_SIG 2034config KEXEC_SIG
2035 bool "Verify kernel signature during kexec_file_load() syscall" 2035 bool "Verify kernel signature during kexec_file_load() syscall"
2036 depends on KEXEC_FILE 2036 depends on KEXEC_FILE
2037 ---help--- 2037 ---help---
2038 This option makes kernel signature verification mandatory for
2039 the kexec_file_load() syscall.
2040 2038
2041 In addition to that option, you need to enable signature 2039 This option makes the kexec_file_load() syscall check for a valid
2040 signature of the kernel image. The image can still be loaded without
2041 a valid signature unless you also enable KEXEC_SIG_FORCE, though if
2042 there's a signature that we can check, then it must be valid.
2043
2044 In addition to this option, you need to enable signature
2042 verification for the corresponding kernel image type being 2045 verification for the corresponding kernel image type being
2043 loaded in order for this to work. 2046 loaded in order for this to work.
2044 2047
2048config KEXEC_SIG_FORCE
2049 bool "Require a valid signature in kexec_file_load() syscall"
2050 depends on KEXEC_SIG
2051 ---help---
2052 This option makes kernel signature verification mandatory for
2053 the kexec_file_load() syscall.
2054
2045config KEXEC_BZIMAGE_VERIFY_SIG 2055config KEXEC_BZIMAGE_VERIFY_SIG
2046 bool "Enable bzImage signature verification support" 2056 bool "Enable bzImage signature verification support"
2047 depends on KEXEC_VERIFY_SIG 2057 depends on KEXEC_SIG
2048 depends on SIGNED_PE_FILE_VERIFICATION 2058 depends on SIGNED_PE_FILE_VERIFICATION
2049 select SYSTEM_TRUSTED_KEYRING 2059 select SYSTEM_TRUSTED_KEYRING
2050 ---help--- 2060 ---help---
diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c
index 15255f388a85..149795c369f2 100644
--- a/arch/x86/boot/compressed/acpi.c
+++ b/arch/x86/boot/compressed/acpi.c
@@ -26,7 +26,7 @@ struct mem_vector immovable_mem[MAX_NUMNODES*2];
26 */ 26 */
27#define MAX_ADDR_LEN 19 27#define MAX_ADDR_LEN 19
28 28
29static acpi_physical_address get_acpi_rsdp(void) 29static acpi_physical_address get_cmdline_acpi_rsdp(void)
30{ 30{
31 acpi_physical_address addr = 0; 31 acpi_physical_address addr = 0;
32 32
@@ -278,10 +278,7 @@ acpi_physical_address get_rsdp_addr(void)
278{ 278{
279 acpi_physical_address pa; 279 acpi_physical_address pa;
280 280
281 pa = get_acpi_rsdp(); 281 pa = boot_params->acpi_rsdp_addr;
282
283 if (!pa)
284 pa = boot_params->acpi_rsdp_addr;
285 282
286 /* 283 /*
287 * Try to get EFI data from setup_data. This can happen when we're a 284 * Try to get EFI data from setup_data. This can happen when we're a
@@ -311,7 +308,17 @@ static unsigned long get_acpi_srat_table(void)
311 char arg[10]; 308 char arg[10];
312 u8 *entry; 309 u8 *entry;
313 310
314 rsdp = (struct acpi_table_rsdp *)(long)boot_params->acpi_rsdp_addr; 311 /*
312 * Check whether we were given an RSDP on the command line. We don't
313 * stash this in boot params because the kernel itself may have
314 * different ideas about whether to trust a command-line parameter.
315 */
316 rsdp = (struct acpi_table_rsdp *)get_cmdline_acpi_rsdp();
317
318 if (!rsdp)
319 rsdp = (struct acpi_table_rsdp *)(long)
320 boot_params->acpi_rsdp_addr;
321
315 if (!rsdp) 322 if (!rsdp)
316 return 0; 323 return 0;
317 324
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index aac686e1e005..bc9693c9107e 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -117,6 +117,12 @@ static inline bool acpi_has_cpu_in_madt(void)
117 return !!acpi_lapic; 117 return !!acpi_lapic;
118} 118}
119 119
120#define ACPI_HAVE_ARCH_SET_ROOT_POINTER
121static inline void acpi_arch_set_root_pointer(u64 addr)
122{
123 x86_init.acpi.set_root_pointer(addr);
124}
125
120#define ACPI_HAVE_ARCH_GET_ROOT_POINTER 126#define ACPI_HAVE_ARCH_GET_ROOT_POINTER
121static inline u64 acpi_arch_get_root_pointer(void) 127static inline u64 acpi_arch_get_root_pointer(void)
122{ 128{
@@ -125,6 +131,7 @@ static inline u64 acpi_arch_get_root_pointer(void)
125 131
126void acpi_generic_reduced_hw_init(void); 132void acpi_generic_reduced_hw_init(void);
127 133
134void x86_default_set_root_pointer(u64 addr);
128u64 x86_default_get_root_pointer(void); 135u64 x86_default_get_root_pointer(void);
129 136
130#else /* !CONFIG_ACPI */ 137#else /* !CONFIG_ACPI */
@@ -138,6 +145,8 @@ static inline void disable_acpi(void) { }
138 145
139static inline void acpi_generic_reduced_hw_init(void) { } 146static inline void acpi_generic_reduced_hw_init(void) { }
140 147
148static inline void x86_default_set_root_pointer(u64 addr) { }
149
141static inline u64 x86_default_get_root_pointer(void) 150static inline u64 x86_default_get_root_pointer(void)
142{ 151{
143 return 0; 152 return 0;
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index ac0934189017..19435858df5f 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -134,10 +134,12 @@ struct x86_hyper_init {
134 134
135/** 135/**
136 * struct x86_init_acpi - x86 ACPI init functions 136 * struct x86_init_acpi - x86 ACPI init functions
137 * @set_root_poitner: set RSDP address
137 * @get_root_pointer: get RSDP address 138 * @get_root_pointer: get RSDP address
138 * @reduced_hw_early_init: hardware reduced platform early init 139 * @reduced_hw_early_init: hardware reduced platform early init
139 */ 140 */
140struct x86_init_acpi { 141struct x86_init_acpi {
142 void (*set_root_pointer)(u64 addr);
141 u64 (*get_root_pointer)(void); 143 u64 (*get_root_pointer)(void);
142 void (*reduced_hw_early_init)(void); 144 void (*reduced_hw_early_init)(void);
143}; 145};
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 17b33ef604f3..04205ce127a1 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1760,6 +1760,11 @@ void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
1760 e820__update_table_print(); 1760 e820__update_table_print();
1761} 1761}
1762 1762
1763void x86_default_set_root_pointer(u64 addr)
1764{
1765 boot_params.acpi_rsdp_addr = addr;
1766}
1767
1763u64 x86_default_get_root_pointer(void) 1768u64 x86_default_get_root_pointer(void)
1764{ 1769{
1765 return boot_params.acpi_rsdp_addr; 1770 return boot_params.acpi_rsdp_addr;
diff --git a/arch/x86/kernel/ima_arch.c b/arch/x86/kernel/ima_arch.c
index 4c407833faca..4d4f5d9faac3 100644
--- a/arch/x86/kernel/ima_arch.c
+++ b/arch/x86/kernel/ima_arch.c
@@ -74,9 +74,9 @@ bool arch_ima_get_secureboot(void)
74 74
75/* secureboot arch rules */ 75/* secureboot arch rules */
76static const char * const sb_arch_rules[] = { 76static const char * const sb_arch_rules[] = {
77#if !IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) 77#if !IS_ENABLED(CONFIG_KEXEC_SIG)
78 "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig", 78 "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig",
79#endif /* CONFIG_KEXEC_VERIFY_SIG */ 79#endif /* CONFIG_KEXEC_SIG */
80 "measure func=KEXEC_KERNEL_CHECK", 80 "measure func=KEXEC_KERNEL_CHECK",
81#if !IS_ENABLED(CONFIG_MODULE_SIG) 81#if !IS_ENABLED(CONFIG_MODULE_SIG)
82 "appraise func=MODULE_CHECK appraise_type=imasig", 82 "appraise func=MODULE_CHECK appraise_type=imasig",
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 0fe1c8782208..61a89d3c0382 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -11,6 +11,7 @@
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/ioport.h> 13#include <linux/ioport.h>
14#include <linux/security.h>
14#include <linux/smp.h> 15#include <linux/smp.h>
15#include <linux/stddef.h> 16#include <linux/stddef.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
@@ -31,7 +32,8 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)
31 32
32 if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) 33 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
33 return -EINVAL; 34 return -EINVAL;
34 if (turn_on && !capable(CAP_SYS_RAWIO)) 35 if (turn_on && (!capable(CAP_SYS_RAWIO) ||
36 security_locked_down(LOCKDOWN_IOPORT)))
35 return -EPERM; 37 return -EPERM;
36 38
37 /* 39 /*
@@ -126,7 +128,8 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
126 return -EINVAL; 128 return -EINVAL;
127 /* Trying to gain more privileges? */ 129 /* Trying to gain more privileges? */
128 if (level > old) { 130 if (level > old) {
129 if (!capable(CAP_SYS_RAWIO)) 131 if (!capable(CAP_SYS_RAWIO) ||
132 security_locked_down(LOCKDOWN_IOPORT))
130 return -EPERM; 133 return -EPERM;
131 } 134 }
132 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | 135 regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 5ebcd02cbca7..d2f4e706a428 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -180,6 +180,7 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
180 if (efi_enabled(EFI_OLD_MEMMAP)) 180 if (efi_enabled(EFI_OLD_MEMMAP))
181 return 0; 181 return 0;
182 182
183 params->secure_boot = boot_params.secure_boot;
183 ei->efi_loader_signature = current_ei->efi_loader_signature; 184 ei->efi_loader_signature = current_ei->efi_loader_signature;
184 ei->efi_systab = current_ei->efi_systab; 185 ei->efi_systab = current_ei->efi_systab;
185 ei->efi_systab_hi = current_ei->efi_systab_hi; 186 ei->efi_systab_hi = current_ei->efi_systab_hi;
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 3db2252b958d..1547be359d7f 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -34,6 +34,7 @@
34#include <linux/notifier.h> 34#include <linux/notifier.h>
35#include <linux/uaccess.h> 35#include <linux/uaccess.h>
36#include <linux/gfp.h> 36#include <linux/gfp.h>
37#include <linux/security.h>
37 38
38#include <asm/cpufeature.h> 39#include <asm/cpufeature.h>
39#include <asm/msr.h> 40#include <asm/msr.h>
@@ -79,6 +80,10 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
79 int err = 0; 80 int err = 0;
80 ssize_t bytes = 0; 81 ssize_t bytes = 0;
81 82
83 err = security_locked_down(LOCKDOWN_MSR);
84 if (err)
85 return err;
86
82 if (count % 8) 87 if (count % 8)
83 return -EINVAL; /* Invalid chunk size */ 88 return -EINVAL; /* Invalid chunk size */
84 89
@@ -130,6 +135,9 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
130 err = -EFAULT; 135 err = -EFAULT;
131 break; 136 break;
132 } 137 }
138 err = security_locked_down(LOCKDOWN_MSR);
139 if (err)
140 break;
133 err = wrmsr_safe_regs_on_cpu(cpu, regs); 141 err = wrmsr_safe_regs_on_cpu(cpu, regs);
134 if (err) 142 if (err)
135 break; 143 break;
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 1bef687faf22..18a799c8fa28 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -95,6 +95,7 @@ struct x86_init_ops x86_init __initdata = {
95 }, 95 },
96 96
97 .acpi = { 97 .acpi = {
98 .set_root_pointer = x86_default_set_root_pointer,
98 .get_root_pointer = x86_default_get_root_pointer, 99 .get_root_pointer = x86_default_get_root_pointer,
99 .reduced_hw_early_init = acpi_generic_reduced_hw_init, 100 .reduced_hw_early_init = acpi_generic_reduced_hw_init,
100 }, 101 },
diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c
index 0881e1ff1e58..a8bd952e136d 100644
--- a/arch/x86/mm/testmmiotrace.c
+++ b/arch/x86/mm/testmmiotrace.c
@@ -8,6 +8,7 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/io.h> 9#include <linux/io.h>
10#include <linux/mmiotrace.h> 10#include <linux/mmiotrace.h>
11#include <linux/security.h>
11 12
12static unsigned long mmio_address; 13static unsigned long mmio_address;
13module_param_hw(mmio_address, ulong, iomem, 0); 14module_param_hw(mmio_address, ulong, iomem, 0);
@@ -115,6 +116,10 @@ static void do_test_bulk_ioremapping(void)
115static int __init init(void) 116static int __init init(void)
116{ 117{
117 unsigned long size = (read_far) ? (8 << 20) : (16 << 10); 118 unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
119 int ret = security_locked_down(LOCKDOWN_MMIOTRACE);
120
121 if (ret)
122 return ret;
118 123
119 if (mmio_address == 0) { 124 if (mmio_address == 0) {
120 pr_err("you have to use the module argument mmio_address.\n"); 125 pr_err("you have to use the module argument mmio_address.\n");
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c
index 3b303fe2f061..cc9dbcecaaca 100644
--- a/crypto/asymmetric_keys/verify_pefile.c
+++ b/crypto/asymmetric_keys/verify_pefile.c
@@ -96,7 +96,7 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen,
96 96
97 if (!ddir->certs.virtual_address || !ddir->certs.size) { 97 if (!ddir->certs.virtual_address || !ddir->certs.size) {
98 pr_debug("Unsigned PE binary\n"); 98 pr_debug("Unsigned PE binary\n");
99 return -EKEYREJECTED; 99 return -ENODATA;
100 } 100 }
101 101
102 chkaddr(ctx->header_size, ddir->certs.virtual_address, 102 chkaddr(ctx->header_size, ddir->certs.virtual_address,
@@ -403,6 +403,8 @@ error_no_desc:
403 * (*) 0 if at least one signature chain intersects with the keys in the trust 403 * (*) 0 if at least one signature chain intersects with the keys in the trust
404 * keyring, or: 404 * keyring, or:
405 * 405 *
406 * (*) -ENODATA if there is no signature present.
407 *
406 * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a 408 * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a
407 * chain. 409 * chain.
408 * 410 *
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
index fd66a736621c..b097ef209313 100644
--- a/drivers/acpi/custom_method.c
+++ b/drivers/acpi/custom_method.c
@@ -9,6 +9,7 @@
9#include <linux/uaccess.h> 9#include <linux/uaccess.h>
10#include <linux/debugfs.h> 10#include <linux/debugfs.h>
11#include <linux/acpi.h> 11#include <linux/acpi.h>
12#include <linux/security.h>
12 13
13#include "internal.h" 14#include "internal.h"
14 15
@@ -29,6 +30,11 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
29 30
30 struct acpi_table_header table; 31 struct acpi_table_header table;
31 acpi_status status; 32 acpi_status status;
33 int ret;
34
35 ret = security_locked_down(LOCKDOWN_ACPI_TABLES);
36 if (ret)
37 return ret;
32 38
33 if (!(*ppos)) { 39 if (!(*ppos)) {
34 /* parse the table header to get the table length */ 40 /* parse the table header to get the table length */
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 2f9d0d20b836..a2e844a8e9ed 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -27,6 +27,7 @@
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/jiffies.h> 28#include <linux/jiffies.h>
29#include <linux/semaphore.h> 29#include <linux/semaphore.h>
30#include <linux/security.h>
30 31
31#include <asm/io.h> 32#include <asm/io.h>
32#include <linux/uaccess.h> 33#include <linux/uaccess.h>
@@ -182,8 +183,19 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
182 acpi_physical_address pa; 183 acpi_physical_address pa;
183 184
184#ifdef CONFIG_KEXEC 185#ifdef CONFIG_KEXEC
185 if (acpi_rsdp) 186 /*
187 * We may have been provided with an RSDP on the command line,
188 * but if a malicious user has done so they may be pointing us
189 * at modified ACPI tables that could alter kernel behaviour -
190 * so, we check the lockdown status before making use of
191 * it. If we trust it then also stash it in an architecture
192 * specific location (if appropriate) so it can be carried
193 * over further kexec()s.
194 */
195 if (acpi_rsdp && !security_locked_down(LOCKDOWN_ACPI_TABLES)) {
196 acpi_arch_set_root_pointer(acpi_rsdp);
186 return acpi_rsdp; 197 return acpi_rsdp;
198 }
187#endif 199#endif
188 pa = acpi_arch_get_root_pointer(); 200 pa = acpi_arch_get_root_pointer();
189 if (pa) 201 if (pa)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index b32327759380..180ac4329763 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -20,6 +20,7 @@
20#include <linux/memblock.h> 20#include <linux/memblock.h>
21#include <linux/earlycpio.h> 21#include <linux/earlycpio.h>
22#include <linux/initrd.h> 22#include <linux/initrd.h>
23#include <linux/security.h>
23#include "internal.h" 24#include "internal.h"
24 25
25#ifdef CONFIG_ACPI_CUSTOM_DSDT 26#ifdef CONFIG_ACPI_CUSTOM_DSDT
@@ -578,6 +579,11 @@ void __init acpi_table_upgrade(void)
578 if (table_nr == 0) 579 if (table_nr == 0)
579 return; 580 return;
580 581
582 if (security_locked_down(LOCKDOWN_ACPI_TABLES)) {
583 pr_notice("kernel is locked down, ignoring table override\n");
584 return;
585 }
586
581 acpi_tables_addr = 587 acpi_tables_addr =
582 memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS, 588 memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
583 all_tables_size, PAGE_SIZE); 589 all_tables_size, PAGE_SIZE);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 9eb564c002f6..43dd0891ca1e 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -29,8 +29,8 @@
29#include <linux/export.h> 29#include <linux/export.h>
30#include <linux/io.h> 30#include <linux/io.h>
31#include <linux/uio.h> 31#include <linux/uio.h>
32
33#include <linux/uaccess.h> 32#include <linux/uaccess.h>
33#include <linux/security.h>
34 34
35#ifdef CONFIG_IA64 35#ifdef CONFIG_IA64
36# include <linux/efi.h> 36# include <linux/efi.h>
@@ -807,7 +807,10 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
807 807
808static int open_port(struct inode *inode, struct file *filp) 808static int open_port(struct inode *inode, struct file *filp)
809{ 809{
810 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; 810 if (!capable(CAP_SYS_RAWIO))
811 return -EPERM;
812
813 return security_locked_down(LOCKDOWN_DEV_MEM);
811} 814}
812 815
813#define zero_lseek null_lseek 816#define zero_lseek null_lseek
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 8f1ab04f6743..8d3e778e988b 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -30,6 +30,7 @@
30#include <linux/acpi.h> 30#include <linux/acpi.h>
31#include <linux/ucs2_string.h> 31#include <linux/ucs2_string.h>
32#include <linux/memblock.h> 32#include <linux/memblock.h>
33#include <linux/security.h>
33 34
34#include <asm/early_ioremap.h> 35#include <asm/early_ioremap.h>
35 36
@@ -221,6 +222,11 @@ static void generic_ops_unregister(void)
221static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata; 222static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
222static int __init efivar_ssdt_setup(char *str) 223static int __init efivar_ssdt_setup(char *str)
223{ 224{
225 int ret = security_locked_down(LOCKDOWN_ACPI_TABLES);
226
227 if (ret)
228 return ret;
229
224 if (strlen(str) < sizeof(efivar_ssdt)) 230 if (strlen(str) < sizeof(efivar_ssdt))
225 memcpy(efivar_ssdt, str, strlen(str)); 231 memcpy(efivar_ssdt, str, strlen(str));
226 else 232 else
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 868e35109284..793412954529 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -755,6 +755,11 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
755 unsigned int size = count; 755 unsigned int size = count;
756 loff_t init_off = off; 756 loff_t init_off = off;
757 u8 *data = (u8 *) buf; 757 u8 *data = (u8 *) buf;
758 int ret;
759
760 ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
761 if (ret)
762 return ret;
758 763
759 if (off > dev->cfg_size) 764 if (off > dev->cfg_size)
760 return 0; 765 return 0;
@@ -1016,6 +1021,11 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
1016 int bar = (unsigned long)attr->private; 1021 int bar = (unsigned long)attr->private;
1017 enum pci_mmap_state mmap_type; 1022 enum pci_mmap_state mmap_type;
1018 struct resource *res = &pdev->resource[bar]; 1023 struct resource *res = &pdev->resource[bar];
1024 int ret;
1025
1026 ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
1027 if (ret)
1028 return ret;
1019 1029
1020 if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start)) 1030 if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
1021 return -EINVAL; 1031 return -EINVAL;
@@ -1092,6 +1102,12 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
1092 struct bin_attribute *attr, char *buf, 1102 struct bin_attribute *attr, char *buf,
1093 loff_t off, size_t count) 1103 loff_t off, size_t count)
1094{ 1104{
1105 int ret;
1106
1107 ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
1108 if (ret)
1109 return ret;
1110
1095 return pci_resource_io(filp, kobj, attr, buf, off, count, true); 1111 return pci_resource_io(filp, kobj, attr, buf, off, count, true);
1096} 1112}
1097 1113
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index fe7fe678965b..5495537c60c2 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -13,6 +13,7 @@
13#include <linux/seq_file.h> 13#include <linux/seq_file.h>
14#include <linux/capability.h> 14#include <linux/capability.h>
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16#include <linux/security.h>
16#include <asm/byteorder.h> 17#include <asm/byteorder.h>
17#include "pci.h" 18#include "pci.h"
18 19
@@ -115,7 +116,11 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
115 struct pci_dev *dev = PDE_DATA(ino); 116 struct pci_dev *dev = PDE_DATA(ino);
116 int pos = *ppos; 117 int pos = *ppos;
117 int size = dev->cfg_size; 118 int size = dev->cfg_size;
118 int cnt; 119 int cnt, ret;
120
121 ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
122 if (ret)
123 return ret;
119 124
120 if (pos >= size) 125 if (pos >= size)
121 return 0; 126 return 0;
@@ -196,6 +201,10 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
196#endif /* HAVE_PCI_MMAP */ 201#endif /* HAVE_PCI_MMAP */
197 int ret = 0; 202 int ret = 0;
198 203
204 ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
205 if (ret)
206 return ret;
207
199 switch (cmd) { 208 switch (cmd) {
200 case PCIIOC_CONTROLLER: 209 case PCIIOC_CONTROLLER:
201 ret = pci_domain_nr(dev->bus); 210 ret = pci_domain_nr(dev->bus);
@@ -238,7 +247,8 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
238 struct pci_filp_private *fpriv = file->private_data; 247 struct pci_filp_private *fpriv = file->private_data;
239 int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM; 248 int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM;
240 249
241 if (!capable(CAP_SYS_RAWIO)) 250 if (!capable(CAP_SYS_RAWIO) ||
251 security_locked_down(LOCKDOWN_PCI_ACCESS))
242 return -EPERM; 252 return -EPERM;
243 253
244 if (fpriv->mmap_state == pci_mmap_io) { 254 if (fpriv->mmap_state == pci_mmap_io) {
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
index d96626c614f5..31e39558d49d 100644
--- a/drivers/pci/syscall.c
+++ b/drivers/pci/syscall.c
@@ -7,6 +7,7 @@
7 7
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <linux/pci.h> 9#include <linux/pci.h>
10#include <linux/security.h>
10#include <linux/syscalls.h> 11#include <linux/syscalls.h>
11#include <linux/uaccess.h> 12#include <linux/uaccess.h>
12#include "pci.h" 13#include "pci.h"
@@ -90,7 +91,8 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
90 u32 dword; 91 u32 dword;
91 int err = 0; 92 int err = 0;
92 93
93 if (!capable(CAP_SYS_ADMIN)) 94 if (!capable(CAP_SYS_ADMIN) ||
95 security_locked_down(LOCKDOWN_PCI_ACCESS))
94 return -EPERM; 96 return -EPERM;
95 97
96 dev = pci_get_domain_bus_and_slot(0, bus, dfn); 98 dev = pci_get_domain_bus_and_slot(0, bus, dfn);
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index abd029945cc8..629359fe3513 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -21,6 +21,7 @@
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/security.h>
24#include <asm/byteorder.h> 25#include <asm/byteorder.h>
25#include <asm/unaligned.h> 26#include <asm/unaligned.h>
26 27
@@ -1575,6 +1576,10 @@ static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj,
1575 struct pcmcia_socket *s; 1576 struct pcmcia_socket *s;
1576 int error; 1577 int error;
1577 1578
1579 error = security_locked_down(LOCKDOWN_PCMCIA_CIS);
1580 if (error)
1581 return error;
1582
1578 s = to_socket(container_of(kobj, struct device, kobj)); 1583 s = to_socket(container_of(kobj, struct device, kobj));
1579 1584
1580 if (off) 1585 if (off)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 4223cb496764..6e713be1d4e9 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -22,6 +22,7 @@
22#include <linux/serial_core.h> 22#include <linux/serial_core.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/security.h>
25 26
26#include <linux/irq.h> 27#include <linux/irq.h>
27#include <linux/uaccess.h> 28#include <linux/uaccess.h>
@@ -862,6 +863,10 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
862 goto check_and_exit; 863 goto check_and_exit;
863 } 864 }
864 865
866 retval = security_locked_down(LOCKDOWN_TIOCSSERIAL);
867 if (retval && (change_irq || change_port))
868 goto exit;
869
865 /* 870 /*
866 * Ask the low level driver to verify the settings. 871 * Ask the low level driver to verify the settings.
867 */ 872 */
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 93e4ca6b2ad7..87846aad594b 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -19,6 +19,7 @@
19#include <linux/atomic.h> 19#include <linux/atomic.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/poll.h> 21#include <linux/poll.h>
22#include <linux/security.h>
22 23
23#include "internal.h" 24#include "internal.h"
24 25
@@ -136,6 +137,25 @@ void debugfs_file_put(struct dentry *dentry)
136} 137}
137EXPORT_SYMBOL_GPL(debugfs_file_put); 138EXPORT_SYMBOL_GPL(debugfs_file_put);
138 139
140/*
141 * Only permit access to world-readable files when the kernel is locked down.
142 * We also need to exclude any file that has ways to write or alter it as root
143 * can bypass the permissions check.
144 */
145static bool debugfs_is_locked_down(struct inode *inode,
146 struct file *filp,
147 const struct file_operations *real_fops)
148{
149 if ((inode->i_mode & 07777) == 0444 &&
150 !(filp->f_mode & FMODE_WRITE) &&
151 !real_fops->unlocked_ioctl &&
152 !real_fops->compat_ioctl &&
153 !real_fops->mmap)
154 return false;
155
156 return security_locked_down(LOCKDOWN_DEBUGFS);
157}
158
139static int open_proxy_open(struct inode *inode, struct file *filp) 159static int open_proxy_open(struct inode *inode, struct file *filp)
140{ 160{
141 struct dentry *dentry = F_DENTRY(filp); 161 struct dentry *dentry = F_DENTRY(filp);
@@ -147,6 +167,11 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
147 return r == -EIO ? -ENOENT : r; 167 return r == -EIO ? -ENOENT : r;
148 168
149 real_fops = debugfs_real_fops(filp); 169 real_fops = debugfs_real_fops(filp);
170
171 r = debugfs_is_locked_down(inode, filp, real_fops);
172 if (r)
173 goto out;
174
150 real_fops = fops_get(real_fops); 175 real_fops = fops_get(real_fops);
151 if (!real_fops) { 176 if (!real_fops) {
152 /* Huh? Module did not clean up after itself at exit? */ 177 /* Huh? Module did not clean up after itself at exit? */
@@ -272,6 +297,11 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
272 return r == -EIO ? -ENOENT : r; 297 return r == -EIO ? -ENOENT : r;
273 298
274 real_fops = debugfs_real_fops(filp); 299 real_fops = debugfs_real_fops(filp);
300
301 r = debugfs_is_locked_down(inode, filp, real_fops);
302 if (r)
303 goto out;
304
275 real_fops = fops_get(real_fops); 305 real_fops = fops_get(real_fops);
276 if (!real_fops) { 306 if (!real_fops) {
277 /* Huh? Module did not cleanup after itself at exit? */ 307 /* Huh? Module did not cleanup after itself at exit? */
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 042b688ed124..7b975dbb2bb4 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -26,6 +26,7 @@
26#include <linux/parser.h> 26#include <linux/parser.h>
27#include <linux/magic.h> 27#include <linux/magic.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/security.h>
29 30
30#include "internal.h" 31#include "internal.h"
31 32
@@ -35,6 +36,32 @@ static struct vfsmount *debugfs_mount;
35static int debugfs_mount_count; 36static int debugfs_mount_count;
36static bool debugfs_registered; 37static bool debugfs_registered;
37 38
39/*
40 * Don't allow access attributes to be changed whilst the kernel is locked down
41 * so that we can use the file mode as part of a heuristic to determine whether
42 * to lock down individual files.
43 */
44static int debugfs_setattr(struct dentry *dentry, struct iattr *ia)
45{
46 int ret = security_locked_down(LOCKDOWN_DEBUGFS);
47
48 if (ret && (ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
49 return ret;
50 return simple_setattr(dentry, ia);
51}
52
53static const struct inode_operations debugfs_file_inode_operations = {
54 .setattr = debugfs_setattr,
55};
56static const struct inode_operations debugfs_dir_inode_operations = {
57 .lookup = simple_lookup,
58 .setattr = debugfs_setattr,
59};
60static const struct inode_operations debugfs_symlink_inode_operations = {
61 .get_link = simple_get_link,
62 .setattr = debugfs_setattr,
63};
64
38static struct inode *debugfs_get_inode(struct super_block *sb) 65static struct inode *debugfs_get_inode(struct super_block *sb)
39{ 66{
40 struct inode *inode = new_inode(sb); 67 struct inode *inode = new_inode(sb);
@@ -369,6 +396,7 @@ static struct dentry *__debugfs_create_file(const char *name, umode_t mode,
369 inode->i_mode = mode; 396 inode->i_mode = mode;
370 inode->i_private = data; 397 inode->i_private = data;
371 398
399 inode->i_op = &debugfs_file_inode_operations;
372 inode->i_fop = proxy_fops; 400 inode->i_fop = proxy_fops;
373 dentry->d_fsdata = (void *)((unsigned long)real_fops | 401 dentry->d_fsdata = (void *)((unsigned long)real_fops |
374 DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); 402 DEBUGFS_FSDATA_IS_REAL_FOPS_BIT);
@@ -532,7 +560,7 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
532 } 560 }
533 561
534 inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; 562 inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
535 inode->i_op = &simple_dir_inode_operations; 563 inode->i_op = &debugfs_dir_inode_operations;
536 inode->i_fop = &simple_dir_operations; 564 inode->i_fop = &simple_dir_operations;
537 565
538 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 566 /* directory inodes start off with i_nlink == 2 (for "." entry) */
@@ -632,7 +660,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
632 return failed_creating(dentry); 660 return failed_creating(dentry);
633 } 661 }
634 inode->i_mode = S_IFLNK | S_IRWXUGO; 662 inode->i_mode = S_IFLNK | S_IRWXUGO;
635 inode->i_op = &simple_symlink_inode_operations; 663 inode->i_op = &debugfs_symlink_inode_operations;
636 inode->i_link = link; 664 inode->i_link = link;
637 d_instantiate(dentry, inode); 665 d_instantiate(dentry, inode);
638 return end_creating(dentry); 666 return end_creating(dentry);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index f5834488b67d..e2ed8e08cc7a 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -31,6 +31,7 @@
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/memory.h> 32#include <linux/memory.h>
33#include <linux/sched/task.h> 33#include <linux/sched/task.h>
34#include <linux/security.h>
34#include <asm/sections.h> 35#include <asm/sections.h>
35#include "internal.h" 36#include "internal.h"
36 37
@@ -545,9 +546,14 @@ out:
545 546
546static int open_kcore(struct inode *inode, struct file *filp) 547static int open_kcore(struct inode *inode, struct file *filp)
547{ 548{
549 int ret = security_locked_down(LOCKDOWN_KCORE);
550
548 if (!capable(CAP_SYS_RAWIO)) 551 if (!capable(CAP_SYS_RAWIO))
549 return -EPERM; 552 return -EPERM;
550 553
554 if (ret)
555 return ret;
556
551 filp->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL); 557 filp->private_data = kmalloc(PAGE_SIZE, GFP_KERNEL);
552 if (!filp->private_data) 558 if (!filp->private_data)
553 return -ENOMEM; 559 return -ENOMEM;
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index eeeae0475da9..9fc14e38927f 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -20,6 +20,7 @@
20#include <linux/parser.h> 20#include <linux/parser.h>
21#include <linux/magic.h> 21#include <linux/magic.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/security.h>
23 24
24#define TRACEFS_DEFAULT_MODE 0700 25#define TRACEFS_DEFAULT_MODE 0700
25 26
@@ -27,6 +28,25 @@ static struct vfsmount *tracefs_mount;
27static int tracefs_mount_count; 28static int tracefs_mount_count;
28static bool tracefs_registered; 29static bool tracefs_registered;
29 30
31static int default_open_file(struct inode *inode, struct file *filp)
32{
33 struct dentry *dentry = filp->f_path.dentry;
34 struct file_operations *real_fops;
35 int ret;
36
37 if (!dentry)
38 return -EINVAL;
39
40 ret = security_locked_down(LOCKDOWN_TRACEFS);
41 if (ret)
42 return ret;
43
44 real_fops = dentry->d_fsdata;
45 if (!real_fops->open)
46 return 0;
47 return real_fops->open(inode, filp);
48}
49
30static ssize_t default_read_file(struct file *file, char __user *buf, 50static ssize_t default_read_file(struct file *file, char __user *buf,
31 size_t count, loff_t *ppos) 51 size_t count, loff_t *ppos)
32{ 52{
@@ -221,6 +241,12 @@ static int tracefs_apply_options(struct super_block *sb)
221 return 0; 241 return 0;
222} 242}
223 243
244static void tracefs_destroy_inode(struct inode *inode)
245{
246 if (S_ISREG(inode->i_mode))
247 kfree(inode->i_fop);
248}
249
224static int tracefs_remount(struct super_block *sb, int *flags, char *data) 250static int tracefs_remount(struct super_block *sb, int *flags, char *data)
225{ 251{
226 int err; 252 int err;
@@ -257,6 +283,7 @@ static int tracefs_show_options(struct seq_file *m, struct dentry *root)
257static const struct super_operations tracefs_super_operations = { 283static const struct super_operations tracefs_super_operations = {
258 .statfs = simple_statfs, 284 .statfs = simple_statfs,
259 .remount_fs = tracefs_remount, 285 .remount_fs = tracefs_remount,
286 .destroy_inode = tracefs_destroy_inode,
260 .show_options = tracefs_show_options, 287 .show_options = tracefs_show_options,
261}; 288};
262 289
@@ -387,6 +414,7 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
387 struct dentry *parent, void *data, 414 struct dentry *parent, void *data,
388 const struct file_operations *fops) 415 const struct file_operations *fops)
389{ 416{
417 struct file_operations *proxy_fops;
390 struct dentry *dentry; 418 struct dentry *dentry;
391 struct inode *inode; 419 struct inode *inode;
392 420
@@ -402,8 +430,20 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
402 if (unlikely(!inode)) 430 if (unlikely(!inode))
403 return failed_creating(dentry); 431 return failed_creating(dentry);
404 432
433 proxy_fops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
434 if (unlikely(!proxy_fops)) {
435 iput(inode);
436 return failed_creating(dentry);
437 }
438
439 if (!fops)
440 fops = &tracefs_file_operations;
441
442 dentry->d_fsdata = (void *)fops;
443 memcpy(proxy_fops, fops, sizeof(*proxy_fops));
444 proxy_fops->open = default_open_file;
405 inode->i_mode = mode; 445 inode->i_mode = mode;
406 inode->i_fop = fops ? fops : &tracefs_file_operations; 446 inode->i_fop = proxy_fops;
407 inode->i_private = data; 447 inode->i_private = data;
408 d_instantiate(dentry, inode); 448 d_instantiate(dentry, inode);
409 fsnotify_create(dentry->d_parent->d_inode, dentry); 449 fsnotify_create(dentry->d_parent->d_inode, dentry);
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index cd28f63bfbc7..dae64600ccbf 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -215,8 +215,13 @@
215 __start_lsm_info = .; \ 215 __start_lsm_info = .; \
216 KEEP(*(.lsm_info.init)) \ 216 KEEP(*(.lsm_info.init)) \
217 __end_lsm_info = .; 217 __end_lsm_info = .;
218#define EARLY_LSM_TABLE() . = ALIGN(8); \
219 __start_early_lsm_info = .; \
220 KEEP(*(.early_lsm_info.init)) \
221 __end_early_lsm_info = .;
218#else 222#else
219#define LSM_TABLE() 223#define LSM_TABLE()
224#define EARLY_LSM_TABLE()
220#endif 225#endif
221 226
222#define ___OF_TABLE(cfg, name) _OF_TABLE_##cfg(name) 227#define ___OF_TABLE(cfg, name) _OF_TABLE_##cfg(name)
@@ -627,7 +632,8 @@
627 ACPI_PROBE_TABLE(timer) \ 632 ACPI_PROBE_TABLE(timer) \
628 THERMAL_TABLE(governor) \ 633 THERMAL_TABLE(governor) \
629 EARLYCON_TABLE() \ 634 EARLYCON_TABLE() \
630 LSM_TABLE() 635 LSM_TABLE() \
636 EARLY_LSM_TABLE()
631 637
632#define INIT_TEXT \ 638#define INIT_TEXT \
633 *(.init.text .init.text.*) \ 639 *(.init.text .init.text.*) \
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 978cc239f23b..8b4e516bac00 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -643,6 +643,12 @@ bool acpi_gtdt_c3stop(int type);
643int acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem, int *timer_count); 643int acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem, int *timer_count);
644#endif 644#endif
645 645
646#ifndef ACPI_HAVE_ARCH_SET_ROOT_POINTER
647static inline void acpi_arch_set_root_pointer(u64 addr)
648{
649}
650#endif
651
646#ifndef ACPI_HAVE_ARCH_GET_ROOT_POINTER 652#ifndef ACPI_HAVE_ARCH_GET_ROOT_POINTER
647static inline u64 acpi_arch_get_root_pointer(void) 653static inline u64 acpi_arch_get_root_pointer(void)
648{ 654{
diff --git a/include/linux/ima.h b/include/linux/ima.h
index a20ad398d260..1c37f17f7203 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -131,4 +131,13 @@ static inline int ima_inode_removexattr(struct dentry *dentry,
131 return 0; 131 return 0;
132} 132}
133#endif /* CONFIG_IMA_APPRAISE */ 133#endif /* CONFIG_IMA_APPRAISE */
134
135#if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING)
136extern bool ima_appraise_signature(enum kernel_read_file_id func);
137#else
138static inline bool ima_appraise_signature(enum kernel_read_file_id func)
139{
140 return false;
141}
142#endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */
134#endif /* _LINUX_IMA_H */ 143#endif /* _LINUX_IMA_H */
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index cc162f3e6461..1776eb2e43a4 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -125,7 +125,7 @@ typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf,
125 unsigned long cmdline_len); 125 unsigned long cmdline_len);
126typedef int (kexec_cleanup_t)(void *loader_data); 126typedef int (kexec_cleanup_t)(void *loader_data);
127 127
128#ifdef CONFIG_KEXEC_VERIFY_SIG 128#ifdef CONFIG_KEXEC_SIG
129typedef int (kexec_verify_sig_t)(const char *kernel_buf, 129typedef int (kexec_verify_sig_t)(const char *kernel_buf,
130 unsigned long kernel_len); 130 unsigned long kernel_len);
131#endif 131#endif
@@ -134,7 +134,7 @@ struct kexec_file_ops {
134 kexec_probe_t *probe; 134 kexec_probe_t *probe;
135 kexec_load_t *load; 135 kexec_load_t *load;
136 kexec_cleanup_t *cleanup; 136 kexec_cleanup_t *cleanup;
137#ifdef CONFIG_KEXEC_VERIFY_SIG 137#ifdef CONFIG_KEXEC_SIG
138 kexec_verify_sig_t *verify_sig; 138 kexec_verify_sig_t *verify_sig;
139#endif 139#endif
140}; 140};
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 3fced5824aee..a3763247547c 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1449,6 +1449,11 @@
1449 * @bpf_prog_free_security: 1449 * @bpf_prog_free_security:
1450 * Clean up the security information stored inside bpf prog. 1450 * Clean up the security information stored inside bpf prog.
1451 * 1451 *
1452 * @locked_down
1453 * Determine whether a kernel feature that potentially enables arbitrary
1454 * code execution in kernel space should be permitted.
1455 *
1456 * @what: kernel feature being accessed
1452 */ 1457 */
1453union security_list_options { 1458union security_list_options {
1454 int (*binder_set_context_mgr)(struct task_struct *mgr); 1459 int (*binder_set_context_mgr)(struct task_struct *mgr);
@@ -1812,6 +1817,7 @@ union security_list_options {
1812 int (*bpf_prog_alloc_security)(struct bpf_prog_aux *aux); 1817 int (*bpf_prog_alloc_security)(struct bpf_prog_aux *aux);
1813 void (*bpf_prog_free_security)(struct bpf_prog_aux *aux); 1818 void (*bpf_prog_free_security)(struct bpf_prog_aux *aux);
1814#endif /* CONFIG_BPF_SYSCALL */ 1819#endif /* CONFIG_BPF_SYSCALL */
1820 int (*locked_down)(enum lockdown_reason what);
1815}; 1821};
1816 1822
1817struct security_hook_heads { 1823struct security_hook_heads {
@@ -2053,6 +2059,7 @@ struct security_hook_heads {
2053 struct hlist_head bpf_prog_alloc_security; 2059 struct hlist_head bpf_prog_alloc_security;
2054 struct hlist_head bpf_prog_free_security; 2060 struct hlist_head bpf_prog_free_security;
2055#endif /* CONFIG_BPF_SYSCALL */ 2061#endif /* CONFIG_BPF_SYSCALL */
2062 struct hlist_head locked_down;
2056} __randomize_layout; 2063} __randomize_layout;
2057 2064
2058/* 2065/*
@@ -2111,12 +2118,18 @@ struct lsm_info {
2111}; 2118};
2112 2119
2113extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; 2120extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
2121extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
2114 2122
2115#define DEFINE_LSM(lsm) \ 2123#define DEFINE_LSM(lsm) \
2116 static struct lsm_info __lsm_##lsm \ 2124 static struct lsm_info __lsm_##lsm \
2117 __used __section(.lsm_info.init) \ 2125 __used __section(.lsm_info.init) \
2118 __aligned(sizeof(unsigned long)) 2126 __aligned(sizeof(unsigned long))
2119 2127
2128#define DEFINE_EARLY_LSM(lsm) \
2129 static struct lsm_info __early_lsm_##lsm \
2130 __used __section(.early_lsm_info.init) \
2131 __aligned(sizeof(unsigned long))
2132
2120#ifdef CONFIG_SECURITY_SELINUX_DISABLE 2133#ifdef CONFIG_SECURITY_SELINUX_DISABLE
2121/* 2134/*
2122 * Assuring the safety of deleting a security module is up to 2135 * Assuring the safety of deleting a security module is up to
diff --git a/include/linux/security.h b/include/linux/security.h
index ace6fdb604f9..a8d59d612d27 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -77,6 +77,54 @@ enum lsm_event {
77 LSM_POLICY_CHANGE, 77 LSM_POLICY_CHANGE,
78}; 78};
79 79
80/*
81 * These are reasons that can be passed to the security_locked_down()
82 * LSM hook. Lockdown reasons that protect kernel integrity (ie, the
83 * ability for userland to modify kernel code) are placed before
84 * LOCKDOWN_INTEGRITY_MAX. Lockdown reasons that protect kernel
85 * confidentiality (ie, the ability for userland to extract
86 * information from the running kernel that would otherwise be
87 * restricted) are placed before LOCKDOWN_CONFIDENTIALITY_MAX.
88 *
89 * LSM authors should note that the semantics of any given lockdown
90 * reason are not guaranteed to be stable - the same reason may block
91 * one set of features in one kernel release, and a slightly different
92 * set of features in a later kernel release. LSMs that seek to expose
93 * lockdown policy at any level of granularity other than "none",
94 * "integrity" or "confidentiality" are responsible for either
95 * ensuring that they expose a consistent level of functionality to
96 * userland, or ensuring that userland is aware that this is
97 * potentially a moving target. It is easy to misuse this information
98 * in a way that could break userspace. Please be careful not to do
99 * so.
100 *
101 * If you add to this, remember to extend lockdown_reasons in
102 * security/lockdown/lockdown.c.
103 */
104enum lockdown_reason {
105 LOCKDOWN_NONE,
106 LOCKDOWN_MODULE_SIGNATURE,
107 LOCKDOWN_DEV_MEM,
108 LOCKDOWN_KEXEC,
109 LOCKDOWN_HIBERNATION,
110 LOCKDOWN_PCI_ACCESS,
111 LOCKDOWN_IOPORT,
112 LOCKDOWN_MSR,
113 LOCKDOWN_ACPI_TABLES,
114 LOCKDOWN_PCMCIA_CIS,
115 LOCKDOWN_TIOCSSERIAL,
116 LOCKDOWN_MODULE_PARAMETERS,
117 LOCKDOWN_MMIOTRACE,
118 LOCKDOWN_DEBUGFS,
119 LOCKDOWN_INTEGRITY_MAX,
120 LOCKDOWN_KCORE,
121 LOCKDOWN_KPROBES,
122 LOCKDOWN_BPF_READ,
123 LOCKDOWN_PERF,
124 LOCKDOWN_TRACEFS,
125 LOCKDOWN_CONFIDENTIALITY_MAX,
126};
127
80/* These functions are in security/commoncap.c */ 128/* These functions are in security/commoncap.c */
81extern int cap_capable(const struct cred *cred, struct user_namespace *ns, 129extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
82 int cap, unsigned int opts); 130 int cap, unsigned int opts);
@@ -195,6 +243,7 @@ int unregister_blocking_lsm_notifier(struct notifier_block *nb);
195 243
196/* prototypes */ 244/* prototypes */
197extern int security_init(void); 245extern int security_init(void);
246extern int early_security_init(void);
198 247
199/* Security operations */ 248/* Security operations */
200int security_binder_set_context_mgr(struct task_struct *mgr); 249int security_binder_set_context_mgr(struct task_struct *mgr);
@@ -392,6 +441,7 @@ void security_inode_invalidate_secctx(struct inode *inode);
392int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); 441int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
393int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); 442int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
394int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); 443int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
444int security_locked_down(enum lockdown_reason what);
395#else /* CONFIG_SECURITY */ 445#else /* CONFIG_SECURITY */
396 446
397static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data) 447static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -423,6 +473,11 @@ static inline int security_init(void)
423 return 0; 473 return 0;
424} 474}
425 475
476static inline int early_security_init(void)
477{
478 return 0;
479}
480
426static inline int security_binder_set_context_mgr(struct task_struct *mgr) 481static inline int security_binder_set_context_mgr(struct task_struct *mgr)
427{ 482{
428 return 0; 483 return 0;
@@ -1210,6 +1265,10 @@ static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32
1210{ 1265{
1211 return -EOPNOTSUPP; 1266 return -EOPNOTSUPP;
1212} 1267}
1268static inline int security_locked_down(enum lockdown_reason what)
1269{
1270 return 0;
1271}
1213#endif /* CONFIG_SECURITY */ 1272#endif /* CONFIG_SECURITY */
1214 1273
1215#ifdef CONFIG_SECURITY_NETWORK 1274#ifdef CONFIG_SECURITY_NETWORK
diff --git a/init/Kconfig b/init/Kconfig
index 92c867e25a29..b4daad2bac23 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2061,6 +2061,11 @@ config MODULE_SIG
2061 kernel build dependency so that the signing tool can use its crypto 2061 kernel build dependency so that the signing tool can use its crypto
2062 library. 2062 library.
2063 2063
2064 You should enable this option if you wish to use either
2065 CONFIG_SECURITY_LOCKDOWN_LSM or lockdown functionality imposed via
2066 another LSM - otherwise unsigned modules will be loadable regardless
2067 of the lockdown policy.
2068
2064 !!!WARNING!!! If you enable this option, you MUST make sure that the 2069 !!!WARNING!!! If you enable this option, you MUST make sure that the
2065 module DOES NOT get stripped after being signed. This includes the 2070 module DOES NOT get stripped after being signed. This includes the
2066 debuginfo strip done by some packagers (such as rpmbuild) and 2071 debuginfo strip done by some packagers (such as rpmbuild) and
diff --git a/init/main.c b/init/main.c
index 208b8fa1808e..91f6ebb30ef0 100644
--- a/init/main.c
+++ b/init/main.c
@@ -593,6 +593,7 @@ asmlinkage __visible void __init start_kernel(void)
593 boot_cpu_init(); 593 boot_cpu_init();
594 page_address_init(); 594 page_address_init();
595 pr_notice("%s", linux_banner); 595 pr_notice("%s", linux_banner);
596 early_security_init();
596 setup_arch(&command_line); 597 setup_arch(&command_line);
597 setup_command_line(command_line); 598 setup_command_line(command_line);
598 setup_nr_cpu_ids(); 599 setup_nr_cpu_ids();
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 275eae05af20..4655adbbae10 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -10917,6 +10917,13 @@ SYSCALL_DEFINE5(perf_event_open,
10917 perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) 10917 perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
10918 return -EACCES; 10918 return -EACCES;
10919 10919
10920 err = security_locked_down(LOCKDOWN_PERF);
10921 if (err && (attr.sample_type & PERF_SAMPLE_REGS_INTR))
10922 /* REGS_INTR can leak data, lockdown must prevent this */
10923 return err;
10924
10925 err = 0;
10926
10920 /* 10927 /*
10921 * In cgroup mode, the pid argument is used to pass the fd 10928 * In cgroup mode, the pid argument is used to pass the fd
10922 * opened to the cgroup directory in cgroupfs. The cpu argument 10929 * opened to the cgroup directory in cgroupfs. The cpu argument
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 1b018f1a6e0d..bc933c0db9bf 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -206,6 +206,14 @@ static inline int kexec_load_check(unsigned long nr_segments,
206 return result; 206 return result;
207 207
208 /* 208 /*
209 * kexec can be used to circumvent module loading restrictions, so
210 * prevent loading in that case
211 */
212 result = security_locked_down(LOCKDOWN_KEXEC);
213 if (result)
214 return result;
215
216 /*
209 * Verify we have a legal set of flags 217 * Verify we have a legal set of flags
210 * This leaves us room for future extensions. 218 * This leaves us room for future extensions.
211 */ 219 */
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index b8cc032d5620..79f252af7dee 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -88,7 +88,7 @@ int __weak arch_kimage_file_post_load_cleanup(struct kimage *image)
88 return kexec_image_post_load_cleanup_default(image); 88 return kexec_image_post_load_cleanup_default(image);
89} 89}
90 90
91#ifdef CONFIG_KEXEC_VERIFY_SIG 91#ifdef CONFIG_KEXEC_SIG
92static int kexec_image_verify_sig_default(struct kimage *image, void *buf, 92static int kexec_image_verify_sig_default(struct kimage *image, void *buf,
93 unsigned long buf_len) 93 unsigned long buf_len)
94{ 94{
@@ -177,6 +177,59 @@ void kimage_file_post_load_cleanup(struct kimage *image)
177 image->image_loader_data = NULL; 177 image->image_loader_data = NULL;
178} 178}
179 179
180#ifdef CONFIG_KEXEC_SIG
181static int
182kimage_validate_signature(struct kimage *image)
183{
184 const char *reason;
185 int ret;
186
187 ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf,
188 image->kernel_buf_len);
189 switch (ret) {
190 case 0:
191 break;
192
193 /* Certain verification errors are non-fatal if we're not
194 * checking errors, provided we aren't mandating that there
195 * must be a valid signature.
196 */
197 case -ENODATA:
198 reason = "kexec of unsigned image";
199 goto decide;
200 case -ENOPKG:
201 reason = "kexec of image with unsupported crypto";
202 goto decide;
203 case -ENOKEY:
204 reason = "kexec of image with unavailable key";
205 decide:
206 if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) {
207 pr_notice("%s rejected\n", reason);
208 return ret;
209 }
210
211 /* If IMA is guaranteed to appraise a signature on the kexec
212 * image, permit it even if the kernel is otherwise locked
213 * down.
214 */
215 if (!ima_appraise_signature(READING_KEXEC_IMAGE) &&
216 security_locked_down(LOCKDOWN_KEXEC))
217 return -EPERM;
218
219 return 0;
220
221 /* All other errors are fatal, including nomem, unparseable
222 * signatures and signature check failures - even if signatures
223 * aren't required.
224 */
225 default:
226 pr_notice("kernel signature verification failed (%d).\n", ret);
227 }
228
229 return ret;
230}
231#endif
232
180/* 233/*
181 * In file mode list of segments is prepared by kernel. Copy relevant 234 * In file mode list of segments is prepared by kernel. Copy relevant
182 * data from user space, do error checking, prepare segment list 235 * data from user space, do error checking, prepare segment list
@@ -186,7 +239,7 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
186 const char __user *cmdline_ptr, 239 const char __user *cmdline_ptr,
187 unsigned long cmdline_len, unsigned flags) 240 unsigned long cmdline_len, unsigned flags)
188{ 241{
189 int ret = 0; 242 int ret;
190 void *ldata; 243 void *ldata;
191 loff_t size; 244 loff_t size;
192 245
@@ -202,14 +255,11 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
202 if (ret) 255 if (ret)
203 goto out; 256 goto out;
204 257
205#ifdef CONFIG_KEXEC_VERIFY_SIG 258#ifdef CONFIG_KEXEC_SIG
206 ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf, 259 ret = kimage_validate_signature(image);
207 image->kernel_buf_len); 260
208 if (ret) { 261 if (ret)
209 pr_debug("kernel signature verification failed.\n");
210 goto out; 262 goto out;
211 }
212 pr_debug("kernel signature verification successful.\n");
213#endif 263#endif
214 /* It is possible that there no initramfs is being loaded */ 264 /* It is possible that there no initramfs is being loaded */
215 if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { 265 if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
diff --git a/kernel/module.c b/kernel/module.c
index edbe42755a27..ff2d7359a418 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2839,8 +2839,9 @@ static inline void kmemleak_load_module(const struct module *mod,
2839#ifdef CONFIG_MODULE_SIG 2839#ifdef CONFIG_MODULE_SIG
2840static int module_sig_check(struct load_info *info, int flags) 2840static int module_sig_check(struct load_info *info, int flags)
2841{ 2841{
2842 int err = -ENOKEY; 2842 int err = -ENODATA;
2843 const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; 2843 const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
2844 const char *reason;
2844 const void *mod = info->hdr; 2845 const void *mod = info->hdr;
2845 2846
2846 /* 2847 /*
@@ -2855,16 +2856,38 @@ static int module_sig_check(struct load_info *info, int flags)
2855 err = mod_verify_sig(mod, info); 2856 err = mod_verify_sig(mod, info);
2856 } 2857 }
2857 2858
2858 if (!err) { 2859 switch (err) {
2860 case 0:
2859 info->sig_ok = true; 2861 info->sig_ok = true;
2860 return 0; 2862 return 0;
2861 }
2862 2863
2863 /* Not having a signature is only an error if we're strict. */ 2864 /* We don't permit modules to be loaded into trusted kernels
2864 if (err == -ENOKEY && !is_module_sig_enforced()) 2865 * without a valid signature on them, but if we're not
2865 err = 0; 2866 * enforcing, certain errors are non-fatal.
2867 */
2868 case -ENODATA:
2869 reason = "Loading of unsigned module";
2870 goto decide;
2871 case -ENOPKG:
2872 reason = "Loading of module with unsupported crypto";
2873 goto decide;
2874 case -ENOKEY:
2875 reason = "Loading of module with unavailable key";
2876 decide:
2877 if (is_module_sig_enforced()) {
2878 pr_notice("%s is rejected\n", reason);
2879 return -EKEYREJECTED;
2880 }
2866 2881
2867 return err; 2882 return security_locked_down(LOCKDOWN_MODULE_SIGNATURE);
2883
2884 /* All other errors are fatal, including nomem, unparseable
2885 * signatures and signature check failures - even if signatures
2886 * aren't required.
2887 */
2888 default:
2889 return err;
2890 }
2868} 2891}
2869#else /* !CONFIG_MODULE_SIG */ 2892#else /* !CONFIG_MODULE_SIG */
2870static int module_sig_check(struct load_info *info, int flags) 2893static int module_sig_check(struct load_info *info, int flags)
diff --git a/kernel/params.c b/kernel/params.c
index cf448785d058..8e56f8b12d8f 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -12,6 +12,7 @@
12#include <linux/err.h> 12#include <linux/err.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/ctype.h> 14#include <linux/ctype.h>
15#include <linux/security.h>
15 16
16#ifdef CONFIG_SYSFS 17#ifdef CONFIG_SYSFS
17/* Protects all built-in parameters, modules use their own param_lock */ 18/* Protects all built-in parameters, modules use their own param_lock */
@@ -96,13 +97,19 @@ bool parameq(const char *a, const char *b)
96 return parameqn(a, b, strlen(a)+1); 97 return parameqn(a, b, strlen(a)+1);
97} 98}
98 99
99static void param_check_unsafe(const struct kernel_param *kp) 100static bool param_check_unsafe(const struct kernel_param *kp)
100{ 101{
102 if (kp->flags & KERNEL_PARAM_FL_HWPARAM &&
103 security_locked_down(LOCKDOWN_MODULE_PARAMETERS))
104 return false;
105
101 if (kp->flags & KERNEL_PARAM_FL_UNSAFE) { 106 if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
102 pr_notice("Setting dangerous option %s - tainting kernel\n", 107 pr_notice("Setting dangerous option %s - tainting kernel\n",
103 kp->name); 108 kp->name);
104 add_taint(TAINT_USER, LOCKDEP_STILL_OK); 109 add_taint(TAINT_USER, LOCKDEP_STILL_OK);
105 } 110 }
111
112 return true;
106} 113}
107 114
108static int parse_one(char *param, 115static int parse_one(char *param,
@@ -132,8 +139,10 @@ static int parse_one(char *param,
132 pr_debug("handling %s with %p\n", param, 139 pr_debug("handling %s with %p\n", param,
133 params[i].ops->set); 140 params[i].ops->set);
134 kernel_param_lock(params[i].mod); 141 kernel_param_lock(params[i].mod);
135 param_check_unsafe(&params[i]); 142 if (param_check_unsafe(&params[i]))
136 err = params[i].ops->set(val, &params[i]); 143 err = params[i].ops->set(val, &params[i]);
144 else
145 err = -EPERM;
137 kernel_param_unlock(params[i].mod); 146 kernel_param_unlock(params[i].mod);
138 return err; 147 return err;
139 } 148 }
@@ -553,8 +562,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
553 return -EPERM; 562 return -EPERM;
554 563
555 kernel_param_lock(mk->mod); 564 kernel_param_lock(mk->mod);
556 param_check_unsafe(attribute->param); 565 if (param_check_unsafe(attribute->param))
557 err = attribute->param->ops->set(buf, attribute->param); 566 err = attribute->param->ops->set(buf, attribute->param);
567 else
568 err = -EPERM;
558 kernel_param_unlock(mk->mod); 569 kernel_param_unlock(mk->mod);
559 if (!err) 570 if (!err)
560 return len; 571 return len;
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index cd7434e6000d..3c0a5a8170b0 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -30,6 +30,7 @@
30#include <linux/ctype.h> 30#include <linux/ctype.h>
31#include <linux/genhd.h> 31#include <linux/genhd.h>
32#include <linux/ktime.h> 32#include <linux/ktime.h>
33#include <linux/security.h>
33#include <trace/events/power.h> 34#include <trace/events/power.h>
34 35
35#include "power.h" 36#include "power.h"
@@ -68,7 +69,7 @@ static const struct platform_hibernation_ops *hibernation_ops;
68 69
69bool hibernation_available(void) 70bool hibernation_available(void)
70{ 71{
71 return (nohibernate == 0); 72 return nohibernate == 0 && !security_locked_down(LOCKDOWN_HIBERNATION);
72} 73}
73 74
74/** 75/**
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index ca1255d14576..492a8bfaae98 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -142,8 +142,13 @@ BPF_CALL_3(bpf_probe_read, void *, dst, u32, size, const void *, unsafe_ptr)
142{ 142{
143 int ret; 143 int ret;
144 144
145 ret = security_locked_down(LOCKDOWN_BPF_READ);
146 if (ret < 0)
147 goto out;
148
145 ret = probe_kernel_read(dst, unsafe_ptr, size); 149 ret = probe_kernel_read(dst, unsafe_ptr, size);
146 if (unlikely(ret < 0)) 150 if (unlikely(ret < 0))
151out:
147 memset(dst, 0, size); 152 memset(dst, 0, size);
148 153
149 return ret; 154 return ret;
@@ -569,6 +574,10 @@ BPF_CALL_3(bpf_probe_read_str, void *, dst, u32, size,
569{ 574{
570 int ret; 575 int ret;
571 576
577 ret = security_locked_down(LOCKDOWN_BPF_READ);
578 if (ret < 0)
579 goto out;
580
572 /* 581 /*
573 * The strncpy_from_unsafe() call will likely not fill the entire 582 * The strncpy_from_unsafe() call will likely not fill the entire
574 * buffer, but that's okay in this circumstance as we're probing 583 * buffer, but that's okay in this circumstance as we're probing
@@ -580,6 +589,7 @@ BPF_CALL_3(bpf_probe_read_str, void *, dst, u32, size,
580 */ 589 */
581 ret = strncpy_from_unsafe(dst, unsafe_ptr, size); 590 ret = strncpy_from_unsafe(dst, unsafe_ptr, size);
582 if (unlikely(ret < 0)) 591 if (unlikely(ret < 0))
592out:
583 memset(dst, 0, size); 593 memset(dst, 0, size);
584 594
585 return ret; 595 return ret;
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 402dc3ce88d3..324ffbea3556 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -11,6 +11,7 @@
11#include <linux/uaccess.h> 11#include <linux/uaccess.h>
12#include <linux/rculist.h> 12#include <linux/rculist.h>
13#include <linux/error-injection.h> 13#include <linux/error-injection.h>
14#include <linux/security.h>
14 15
15#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ 16#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
16 17
@@ -460,6 +461,10 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
460{ 461{
461 int i, ret; 462 int i, ret;
462 463
464 ret = security_locked_down(LOCKDOWN_KPROBES);
465 if (ret)
466 return ret;
467
463 if (trace_kprobe_is_registered(tk)) 468 if (trace_kprobe_is_registered(tk))
464 return -EINVAL; 469 return -EINVAL;
465 470
diff --git a/security/Kconfig b/security/Kconfig
index 0d65594b5196..2a1a2d396228 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -237,6 +237,7 @@ source "security/apparmor/Kconfig"
237source "security/loadpin/Kconfig" 237source "security/loadpin/Kconfig"
238source "security/yama/Kconfig" 238source "security/yama/Kconfig"
239source "security/safesetid/Kconfig" 239source "security/safesetid/Kconfig"
240source "security/lockdown/Kconfig"
240 241
241source "security/integrity/Kconfig" 242source "security/integrity/Kconfig"
242 243
@@ -276,11 +277,11 @@ endchoice
276 277
277config LSM 278config LSM
278 string "Ordered list of enabled LSMs" 279 string "Ordered list of enabled LSMs"
279 default "yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor" if DEFAULT_SECURITY_SMACK 280 default "lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor" if DEFAULT_SECURITY_SMACK
280 default "yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo" if DEFAULT_SECURITY_APPARMOR 281 default "lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo" if DEFAULT_SECURITY_APPARMOR
281 default "yama,loadpin,safesetid,integrity,tomoyo" if DEFAULT_SECURITY_TOMOYO 282 default "lockdown,yama,loadpin,safesetid,integrity,tomoyo" if DEFAULT_SECURITY_TOMOYO
282 default "yama,loadpin,safesetid,integrity" if DEFAULT_SECURITY_DAC 283 default "lockdown,yama,loadpin,safesetid,integrity" if DEFAULT_SECURITY_DAC
283 default "yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor" 284 default "lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor"
284 help 285 help
285 A comma-separated list of LSMs, in initialization order. 286 A comma-separated list of LSMs, in initialization order.
286 Any LSMs left off this list will be ignored. This can be 287 Any LSMs left off this list will be ignored. This can be
diff --git a/security/Makefile b/security/Makefile
index c598b904938f..be1dd9d2cb2f 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -11,6 +11,7 @@ subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
11subdir-$(CONFIG_SECURITY_YAMA) += yama 11subdir-$(CONFIG_SECURITY_YAMA) += yama
12subdir-$(CONFIG_SECURITY_LOADPIN) += loadpin 12subdir-$(CONFIG_SECURITY_LOADPIN) += loadpin
13subdir-$(CONFIG_SECURITY_SAFESETID) += safesetid 13subdir-$(CONFIG_SECURITY_SAFESETID) += safesetid
14subdir-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown
14 15
15# always enable default capabilities 16# always enable default capabilities
16obj-y += commoncap.o 17obj-y += commoncap.o
@@ -27,6 +28,7 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/
27obj-$(CONFIG_SECURITY_YAMA) += yama/ 28obj-$(CONFIG_SECURITY_YAMA) += yama/
28obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/ 29obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/
29obj-$(CONFIG_SECURITY_SAFESETID) += safesetid/ 30obj-$(CONFIG_SECURITY_SAFESETID) += safesetid/
31obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown/
30obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 32obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
31 33
32# Object integrity file lists 34# Object integrity file lists
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 897bafc59a33..838476d780e5 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -160,7 +160,7 @@ config IMA_APPRAISE
160 160
161config IMA_ARCH_POLICY 161config IMA_ARCH_POLICY
162 bool "Enable loading an IMA architecture specific policy" 162 bool "Enable loading an IMA architecture specific policy"
163 depends on (KEXEC_VERIFY_SIG && IMA) || IMA_APPRAISE \ 163 depends on (KEXEC_SIG && IMA) || IMA_APPRAISE \
164 && INTEGRITY_ASYMMETRIC_KEYS 164 && INTEGRITY_ASYMMETRIC_KEYS
165 default n 165 default n
166 help 166 help
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 19769bf5f6ab..3689081aaf38 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -114,6 +114,8 @@ struct ima_kexec_hdr {
114 u64 count; 114 u64 count;
115}; 115};
116 116
117extern const int read_idmap[];
118
117#ifdef CONFIG_HAVE_IMA_KEXEC 119#ifdef CONFIG_HAVE_IMA_KEXEC
118void ima_load_kexec_buffer(void); 120void ima_load_kexec_buffer(void);
119#else 121#else
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 79c01516211b..60027c643ecd 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -518,7 +518,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id)
518 return 0; 518 return 0;
519} 519}
520 520
521static const int read_idmap[READING_MAX_ID] = { 521const int read_idmap[READING_MAX_ID] = {
522 [READING_FIRMWARE] = FIRMWARE_CHECK, 522 [READING_FIRMWARE] = FIRMWARE_CHECK,
523 [READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK, 523 [READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK,
524 [READING_MODULE] = MODULE_CHECK, 524 [READING_MODULE] = MODULE_CHECK,
@@ -590,7 +590,7 @@ int ima_load_data(enum kernel_load_data_id id)
590 590
591 switch (id) { 591 switch (id) {
592 case LOADING_KEXEC_IMAGE: 592 case LOADING_KEXEC_IMAGE:
593 if (IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) 593 if (IS_ENABLED(CONFIG_KEXEC_SIG)
594 && arch_ima_get_secureboot()) { 594 && arch_ima_get_secureboot()) {
595 pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n"); 595 pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n");
596 return -EACCES; 596 return -EACCES;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 4badc4fcda98..5380aca2b351 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -1507,3 +1507,53 @@ int ima_policy_show(struct seq_file *m, void *v)
1507 return 0; 1507 return 0;
1508} 1508}
1509#endif /* CONFIG_IMA_READ_POLICY */ 1509#endif /* CONFIG_IMA_READ_POLICY */
1510
1511#if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING)
1512/*
1513 * ima_appraise_signature: whether IMA will appraise a given function using
1514 * an IMA digital signature. This is restricted to cases where the kernel
1515 * has a set of built-in trusted keys in order to avoid an attacker simply
1516 * loading additional keys.
1517 */
1518bool ima_appraise_signature(enum kernel_read_file_id id)
1519{
1520 struct ima_rule_entry *entry;
1521 bool found = false;
1522 enum ima_hooks func;
1523
1524 if (id >= READING_MAX_ID)
1525 return false;
1526
1527 func = read_idmap[id] ?: FILE_CHECK;
1528
1529 rcu_read_lock();
1530 list_for_each_entry_rcu(entry, ima_rules, list) {
1531 if (entry->action != APPRAISE)
1532 continue;
1533
1534 /*
1535 * A generic entry will match, but otherwise require that it
1536 * match the func we're looking for
1537 */
1538 if (entry->func && entry->func != func)
1539 continue;
1540
1541 /*
1542 * We require this to be a digital signature, not a raw IMA
1543 * hash.
1544 */
1545 if (entry->flags & IMA_DIGSIG_REQUIRED)
1546 found = true;
1547
1548 /*
1549 * We've found a rule that matches, so break now even if it
1550 * didn't require a digital signature - a later rule that does
1551 * won't override it, so would be a false positive.
1552 */
1553 break;
1554 }
1555
1556 rcu_read_unlock();
1557 return found;
1558}
1559#endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
new file mode 100644
index 000000000000..e84ddf484010
--- /dev/null
+++ b/security/lockdown/Kconfig
@@ -0,0 +1,47 @@
1config SECURITY_LOCKDOWN_LSM
2 bool "Basic module for enforcing kernel lockdown"
3 depends on SECURITY
4 select MODULE_SIG if MODULES
5 help
6 Build support for an LSM that enforces a coarse kernel lockdown
7 behaviour.
8
9config SECURITY_LOCKDOWN_LSM_EARLY
10 bool "Enable lockdown LSM early in init"
11 depends on SECURITY_LOCKDOWN_LSM
12 help
13 Enable the lockdown LSM early in boot. This is necessary in order
14 to ensure that lockdown enforcement can be carried out on kernel
15 boot parameters that are otherwise parsed before the security
16 subsystem is fully initialised. If enabled, lockdown will
17 unconditionally be called before any other LSMs.
18
19choice
20 prompt "Kernel default lockdown mode"
21 default LOCK_DOWN_KERNEL_FORCE_NONE
22 depends on SECURITY_LOCKDOWN_LSM
23 help
24 The kernel can be configured to default to differing levels of
25 lockdown.
26
27config LOCK_DOWN_KERNEL_FORCE_NONE
28 bool "None"
29 help
30 No lockdown functionality is enabled by default. Lockdown may be
31 enabled via the kernel commandline or /sys/kernel/security/lockdown.
32
33config LOCK_DOWN_KERNEL_FORCE_INTEGRITY
34 bool "Integrity"
35 help
36 The kernel runs in integrity mode by default. Features that allow
37 the kernel to be modified at runtime are disabled.
38
39config LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY
40 bool "Confidentiality"
41 help
42 The kernel runs in confidentiality mode by default. Features that
43 allow the kernel to be modified at runtime or that permit userland
44 code to read confidential material held inside the kernel are
45 disabled.
46
47endchoice
diff --git a/security/lockdown/Makefile b/security/lockdown/Makefile
new file mode 100644
index 000000000000..e3634b9017e7
--- /dev/null
+++ b/security/lockdown/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_SECURITY_LOCKDOWN_LSM) += lockdown.o
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
new file mode 100644
index 000000000000..8a10b43daf74
--- /dev/null
+++ b/security/lockdown/lockdown.c
@@ -0,0 +1,191 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Lock down the kernel
3 *
4 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public Licence
9 * as published by the Free Software Foundation; either version
10 * 2 of the Licence, or (at your option) any later version.
11 */
12
13#include <linux/security.h>
14#include <linux/export.h>
15#include <linux/lsm_hooks.h>
16
17static enum lockdown_reason kernel_locked_down;
18
19static const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
20 [LOCKDOWN_NONE] = "none",
21 [LOCKDOWN_MODULE_SIGNATURE] = "unsigned module loading",
22 [LOCKDOWN_DEV_MEM] = "/dev/mem,kmem,port",
23 [LOCKDOWN_KEXEC] = "kexec of unsigned images",
24 [LOCKDOWN_HIBERNATION] = "hibernation",
25 [LOCKDOWN_PCI_ACCESS] = "direct PCI access",
26 [LOCKDOWN_IOPORT] = "raw io port access",
27 [LOCKDOWN_MSR] = "raw MSR access",
28 [LOCKDOWN_ACPI_TABLES] = "modifying ACPI tables",
29 [LOCKDOWN_PCMCIA_CIS] = "direct PCMCIA CIS storage",
30 [LOCKDOWN_TIOCSSERIAL] = "reconfiguration of serial port IO",
31 [LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters",
32 [LOCKDOWN_MMIOTRACE] = "unsafe mmio",
33 [LOCKDOWN_DEBUGFS] = "debugfs access",
34 [LOCKDOWN_INTEGRITY_MAX] = "integrity",
35 [LOCKDOWN_KCORE] = "/proc/kcore access",
36 [LOCKDOWN_KPROBES] = "use of kprobes",
37 [LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM",
38 [LOCKDOWN_PERF] = "unsafe use of perf",
39 [LOCKDOWN_TRACEFS] = "use of tracefs",
40 [LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
41};
42
43static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE,
44 LOCKDOWN_INTEGRITY_MAX,
45 LOCKDOWN_CONFIDENTIALITY_MAX};
46
47/*
48 * Put the kernel into lock-down mode.
49 */
50static int lock_kernel_down(const char *where, enum lockdown_reason level)
51{
52 if (kernel_locked_down >= level)
53 return -EPERM;
54
55 kernel_locked_down = level;
56 pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n",
57 where);
58 return 0;
59}
60
61static int __init lockdown_param(char *level)
62{
63 if (!level)
64 return -EINVAL;
65
66 if (strcmp(level, "integrity") == 0)
67 lock_kernel_down("command line", LOCKDOWN_INTEGRITY_MAX);
68 else if (strcmp(level, "confidentiality") == 0)
69 lock_kernel_down("command line", LOCKDOWN_CONFIDENTIALITY_MAX);
70 else
71 return -EINVAL;
72
73 return 0;
74}
75
76early_param("lockdown", lockdown_param);
77
78/**
79 * lockdown_is_locked_down - Find out if the kernel is locked down
80 * @what: Tag to use in notice generated if lockdown is in effect
81 */
82static int lockdown_is_locked_down(enum lockdown_reason what)
83{
84 if (WARN(what >= LOCKDOWN_CONFIDENTIALITY_MAX,
85 "Invalid lockdown reason"))
86 return -EPERM;
87
88 if (kernel_locked_down >= what) {
89 if (lockdown_reasons[what])
90 pr_notice("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n",
91 current->comm, lockdown_reasons[what]);
92 return -EPERM;
93 }
94
95 return 0;
96}
97
98static struct security_hook_list lockdown_hooks[] __lsm_ro_after_init = {
99 LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
100};
101
102static int __init lockdown_lsm_init(void)
103{
104#if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY)
105 lock_kernel_down("Kernel configuration", LOCKDOWN_INTEGRITY_MAX);
106#elif defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY)
107 lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX);
108#endif
109 security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks),
110 "lockdown");
111 return 0;
112}
113
114static ssize_t lockdown_read(struct file *filp, char __user *buf, size_t count,
115 loff_t *ppos)
116{
117 char temp[80];
118 int i, offset = 0;
119
120 for (i = 0; i < ARRAY_SIZE(lockdown_levels); i++) {
121 enum lockdown_reason level = lockdown_levels[i];
122
123 if (lockdown_reasons[level]) {
124 const char *label = lockdown_reasons[level];
125
126 if (kernel_locked_down == level)
127 offset += sprintf(temp+offset, "[%s] ", label);
128 else
129 offset += sprintf(temp+offset, "%s ", label);
130 }
131 }
132
133 /* Convert the last space to a newline if needed. */
134 if (offset > 0)
135 temp[offset-1] = '\n';
136
137 return simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
138}
139
140static ssize_t lockdown_write(struct file *file, const char __user *buf,
141 size_t n, loff_t *ppos)
142{
143 char *state;
144 int i, len, err = -EINVAL;
145
146 state = memdup_user_nul(buf, n);
147 if (IS_ERR(state))
148 return PTR_ERR(state);
149
150 len = strlen(state);
151 if (len && state[len-1] == '\n') {
152 state[len-1] = '\0';
153 len--;
154 }
155
156 for (i = 0; i < ARRAY_SIZE(lockdown_levels); i++) {
157 enum lockdown_reason level = lockdown_levels[i];
158 const char *label = lockdown_reasons[level];
159
160 if (label && !strcmp(state, label))
161 err = lock_kernel_down("securityfs", level);
162 }
163
164 kfree(state);
165 return err ? err : n;
166}
167
168static const struct file_operations lockdown_ops = {
169 .read = lockdown_read,
170 .write = lockdown_write,
171};
172
173static int __init lockdown_secfs_init(void)
174{
175 struct dentry *dentry;
176
177 dentry = securityfs_create_file("lockdown", 0600, NULL, NULL,
178 &lockdown_ops);
179 return PTR_ERR_OR_ZERO(dentry);
180}
181
182core_initcall(lockdown_secfs_init);
183
184#ifdef CONFIG_SECURITY_LOCKDOWN_LSM_EARLY
185DEFINE_EARLY_LSM(lockdown) = {
186#else
187DEFINE_LSM(lockdown) = {
188#endif
189 .name = "lockdown",
190 .init = lockdown_lsm_init,
191};
diff --git a/security/security.c b/security/security.c
index 25ee5c75551f..1bc000f834e2 100644
--- a/security/security.c
+++ b/security/security.c
@@ -33,6 +33,7 @@
33 33
34/* How many LSMs were built into the kernel? */ 34/* How many LSMs were built into the kernel? */
35#define LSM_COUNT (__end_lsm_info - __start_lsm_info) 35#define LSM_COUNT (__end_lsm_info - __start_lsm_info)
36#define EARLY_LSM_COUNT (__end_early_lsm_info - __start_early_lsm_info)
36 37
37struct security_hook_heads security_hook_heads __lsm_ro_after_init; 38struct security_hook_heads security_hook_heads __lsm_ro_after_init;
38static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain); 39static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
@@ -277,6 +278,8 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
277static void __init lsm_early_cred(struct cred *cred); 278static void __init lsm_early_cred(struct cred *cred);
278static void __init lsm_early_task(struct task_struct *task); 279static void __init lsm_early_task(struct task_struct *task);
279 280
281static int lsm_append(const char *new, char **result);
282
280static void __init ordered_lsm_init(void) 283static void __init ordered_lsm_init(void)
281{ 284{
282 struct lsm_info **lsm; 285 struct lsm_info **lsm;
@@ -323,6 +326,26 @@ static void __init ordered_lsm_init(void)
323 kfree(ordered_lsms); 326 kfree(ordered_lsms);
324} 327}
325 328
329int __init early_security_init(void)
330{
331 int i;
332 struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
333 struct lsm_info *lsm;
334
335 for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
336 i++)
337 INIT_HLIST_HEAD(&list[i]);
338
339 for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
340 if (!lsm->enabled)
341 lsm->enabled = &lsm_enabled_true;
342 prepare_lsm(lsm);
343 initialize_lsm(lsm);
344 }
345
346 return 0;
347}
348
326/** 349/**
327 * security_init - initializes the security framework 350 * security_init - initializes the security framework
328 * 351 *
@@ -330,14 +353,18 @@ static void __init ordered_lsm_init(void)
330 */ 353 */
331int __init security_init(void) 354int __init security_init(void)
332{ 355{
333 int i; 356 struct lsm_info *lsm;
334 struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
335 357
336 pr_info("Security Framework initializing\n"); 358 pr_info("Security Framework initializing\n");
337 359
338 for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head); 360 /*
339 i++) 361 * Append the names of the early LSM modules now that kmalloc() is
340 INIT_HLIST_HEAD(&list[i]); 362 * available
363 */
364 for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
365 if (lsm->enabled)
366 lsm_append(lsm->name, &lsm_names);
367 }
341 368
342 /* Load LSMs in specified order. */ 369 /* Load LSMs in specified order. */
343 ordered_lsm_init(); 370 ordered_lsm_init();
@@ -384,7 +411,7 @@ static bool match_last_lsm(const char *list, const char *lsm)
384 return !strcmp(last, lsm); 411 return !strcmp(last, lsm);
385} 412}
386 413
387static int lsm_append(char *new, char **result) 414static int lsm_append(const char *new, char **result)
388{ 415{
389 char *cp; 416 char *cp;
390 417
@@ -422,8 +449,15 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
422 hooks[i].lsm = lsm; 449 hooks[i].lsm = lsm;
423 hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); 450 hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
424 } 451 }
425 if (lsm_append(lsm, &lsm_names) < 0) 452
426 panic("%s - Cannot get early memory.\n", __func__); 453 /*
454 * Don't try to append during early_security_init(), we'll come back
455 * and fix this up afterwards.
456 */
457 if (slab_is_available()) {
458 if (lsm_append(lsm, &lsm_names) < 0)
459 panic("%s - Cannot get early memory.\n", __func__);
460 }
427} 461}
428 462
429int call_blocking_lsm_notifier(enum lsm_event event, void *data) 463int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -2364,3 +2398,9 @@ void security_bpf_prog_free(struct bpf_prog_aux *aux)
2364 call_void_hook(bpf_prog_free_security, aux); 2398 call_void_hook(bpf_prog_free_security, aux);
2365} 2399}
2366#endif /* CONFIG_BPF_SYSCALL */ 2400#endif /* CONFIG_BPF_SYSCALL */
2401
2402int security_locked_down(enum lockdown_reason what)
2403{
2404 return call_int_hook(locked_down, 0, what);
2405}
2406EXPORT_SYMBOL(security_locked_down);