From 1a17e5b513ceebf21100027745b8731b4728edf7 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 9 Dec 2022 11:54:57 -0800 Subject: LoadPin: Ignore the "contents" argument of the LSM hooks LoadPin only enforces the read-only origin of kernel file reads. Whether or not it was a partial read isn't important. Remove the overly conservative checks so that things like partial firmware reads will succeed (i.e. reading a firmware header). Fixes: 2039bda1fa8d ("LSM: Add "contents" flag to kernel_read_file hook") Cc: Paul Moore Cc: James Morris Cc: "Serge E. Hallyn" Cc: linux-security-module@vger.kernel.org Signed-off-by: Kees Cook Acked-by: Serge Hallyn Tested-by: Ping-Ke Shih Link: https://lore.kernel.org/r/20221209195453.never.494-kees@kernel.org --- security/loadpin/loadpin.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index de41621f4998..110a5ab2b46b 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -122,21 +122,11 @@ static void loadpin_sb_free_security(struct super_block *mnt_sb) } } -static int loadpin_read_file(struct file *file, enum kernel_read_file_id id, - bool contents) +static int loadpin_check(struct file *file, enum kernel_read_file_id id) { struct super_block *load_root; const char *origin = kernel_read_file_id_str(id); - /* - * If we will not know that we'll be seeing the full contents - * then we cannot trust a load will be complete and unchanged - * off disk. Treat all contents=false hooks as if there were - * no associated file struct. - */ - if (!contents) - file = NULL; - /* If the file id is excluded, ignore the pinning. */ if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) && ignore_read_file_id[id]) { @@ -192,9 +182,25 @@ static int loadpin_read_file(struct file *file, enum kernel_read_file_id id, return 0; } +static int loadpin_read_file(struct file *file, enum kernel_read_file_id id, + bool contents) +{ + /* + * LoadPin only cares about the _origin_ of a file, not its + * contents, so we can ignore the "are full contents available" + * argument here. + */ + return loadpin_check(file, id); +} + static int loadpin_load_data(enum kernel_load_data_id id, bool contents) { - return loadpin_read_file(NULL, (enum kernel_read_file_id) id, contents); + /* + * LoadPin only cares about the _origin_ of a file, not its + * contents, so a NULL file is passed, and we can ignore the + * state of "contents". + */ + return loadpin_check(NULL, (enum kernel_read_file_id) id); } static struct security_hook_list loadpin_hooks[] __lsm_ro_after_init = { -- cgit v1.2.3-70-g09d2 From 00dd027f721e0458418f7750d8a5a664ed3e5994 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 14 Dec 2022 14:35:47 -0800 Subject: docs: Fix path paste-o for /sys/kernel/warn_count Running "make htmldocs" shows that "/sys/kernel/oops_count" was duplicated. This should have been "warn_count": Warning: /sys/kernel/oops_count is defined 2 times: ./Documentation/ABI/testing/sysfs-kernel-warn_count:0 ./Documentation/ABI/testing/sysfs-kernel-oops_count:0 Fix the typo. Reported-by: kernel test robot Link: https://lore.kernel.org/linux-doc/202212110529.A3Qav8aR-lkp@intel.com Fixes: 8b05aa263361 ("panic: Expose "warn_count" to sysfs") Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook --- Documentation/ABI/testing/sysfs-kernel-warn_count | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-kernel-warn_count b/Documentation/ABI/testing/sysfs-kernel-warn_count index 08f083d2fd51..90a029813717 100644 --- a/Documentation/ABI/testing/sysfs-kernel-warn_count +++ b/Documentation/ABI/testing/sysfs-kernel-warn_count @@ -1,4 +1,4 @@ -What: /sys/kernel/oops_count +What: /sys/kernel/warn_count Date: November 2022 KernelVersion: 6.2.0 Contact: Linux Kernel Hardening List -- cgit v1.2.3-70-g09d2 From f68022ae0aeb0803450e05abc0e984027c33ef1b Mon Sep 17 00:00:00 2001 From: Kristina Martsenko Date: Fri, 9 Dec 2022 17:34:41 +0000 Subject: lkdtm: cfi: Make PAC test work with GCC 7 and 8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CFI test uses the branch-protection=none compiler attribute to disable PAC return address protection on a function. While newer GCC versions support this attribute, older versions (GCC 7 and 8) instead supported the sign-return-address=none attribute, leading to a build failure when the test is built with older compilers. Fix it by checking which attribute is supported and using the correct one. Fixes: 2e53b877dc12 ("lkdtm: Add CFI_BACKWARD to test ROP mitigations") Reported-by: Daniel Díaz Signed-off-by: Kristina Martsenko Signed-off-by: Kees Cook Link: https://lore.kernel.org/all/CAEUSe78kDPxQmQqCWW-_9LCgJDFhAeMoVBFnX9QLx18Z4uT4VQ@mail.gmail.com/ --- drivers/misc/lkdtm/cfi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/misc/lkdtm/cfi.c b/drivers/misc/lkdtm/cfi.c index 5245cf6013c9..fc28714ae3a6 100644 --- a/drivers/misc/lkdtm/cfi.c +++ b/drivers/misc/lkdtm/cfi.c @@ -54,7 +54,11 @@ static void lkdtm_CFI_FORWARD_PROTO(void) # ifdef CONFIG_ARM64_BTI_KERNEL # define __no_pac "branch-protection=bti" # else -# define __no_pac "branch-protection=none" +# ifdef CONFIG_CC_HAS_BRANCH_PROT_PAC_RET +# define __no_pac "branch-protection=none" +# else +# define __no_pac "sign-return-address=none" +# endif # endif # define __no_ret_protection __noscs __attribute__((__target__(__no_pac))) #else -- cgit v1.2.3-70-g09d2 From d6a9fb87e9d18f3394a9845546bbe868efdccfd2 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Wed, 14 Dec 2022 16:26:03 -0700 Subject: security: Restrict CONFIG_ZERO_CALL_USED_REGS to gcc or clang > 15.0.6 A bad bug in clang's implementation of -fzero-call-used-regs can result in NULL pointer dereferences (see the links above the check for more information). Restrict CONFIG_CC_HAS_ZERO_CALL_USED_REGS to either a supported GCC version or a clang newer than 15.0.6, which will catch both a theoretical 15.0.7 and the upcoming 16.0.0, which will both have the bug fixed. Cc: stable@vger.kernel.org # v5.15+ Signed-off-by: Nathan Chancellor Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20221214232602.4118147-1-nathan@kernel.org --- security/Kconfig.hardening | 3 +++ 1 file changed, 3 insertions(+) diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening index d766b7d0ffd1..53baa95cb644 100644 --- a/security/Kconfig.hardening +++ b/security/Kconfig.hardening @@ -257,6 +257,9 @@ config INIT_ON_FREE_DEFAULT_ON config CC_HAS_ZERO_CALL_USED_REGS def_bool $(cc-option,-fzero-call-used-regs=used-gpr) + # https://github.com/ClangBuiltLinux/linux/issues/1766 + # https://github.com/llvm/llvm-project/issues/59242 + depends on !CC_IS_CLANG || CLANG_VERSION > 150006 config ZERO_CALL_USED_REGS bool "Enable register zeroing on function exit" -- cgit v1.2.3-70-g09d2 From 7535b832c6399b5ebfc5b53af5c51dd915ee2538 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 16 Dec 2022 12:26:57 -0800 Subject: exit: Use READ_ONCE() for all oops/warn limit reads Use a temporary variable to take full advantage of READ_ONCE() behavior. Without this, the report (and even the test) might be out of sync with the initial test. Reported-by: Peter Zijlstra Link: https://lore.kernel.org/lkml/Y5x7GXeluFmZ8E0E@hirez.programming.kicks-ass.net Fixes: 9fc9e278a5c0 ("panic: Introduce warn_limit") Fixes: d4ccd54d28d3 ("exit: Put an upper limit on how often we can oops") Cc: "Eric W. Biederman" Cc: Jann Horn Cc: Arnd Bergmann Cc: Petr Mladek Cc: Andrew Morton Cc: Luis Chamberlain Cc: Marco Elver Cc: tangmeng Cc: Sebastian Andrzej Siewior Cc: Tiezhu Yang Signed-off-by: Kees Cook --- kernel/exit.c | 6 ++++-- kernel/panic.c | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index deffb8e4b1b2..15dc2ec80c46 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -931,6 +931,7 @@ void __noreturn make_task_dead(int signr) * Then do everything else. */ struct task_struct *tsk = current; + unsigned int limit; if (unlikely(in_interrupt())) panic("Aiee, killing interrupt handler!"); @@ -954,8 +955,9 @@ void __noreturn make_task_dead(int signr) * To make sure this can't happen, place an upper bound on how often the * kernel may oops without panic(). */ - if (atomic_inc_return(&oops_count) >= READ_ONCE(oops_limit) && oops_limit) - panic("Oopsed too often (kernel.oops_limit is %d)", oops_limit); + limit = READ_ONCE(oops_limit); + if (atomic_inc_return(&oops_count) >= limit && limit) + panic("Oopsed too often (kernel.oops_limit is %d)", limit); /* * We're taking recursive faults here in make_task_dead. Safest is to just diff --git a/kernel/panic.c b/kernel/panic.c index 54deb743b2d5..7834c9854e02 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -231,12 +231,15 @@ static void panic_print_sys_info(bool console_flush) void check_panic_on_warn(const char *origin) { + unsigned int limit; + if (panic_on_warn) panic("%s: panic_on_warn set ...\n", origin); - if (atomic_inc_return(&warn_count) >= READ_ONCE(warn_limit) && warn_limit) + limit = READ_ONCE(warn_limit); + if (atomic_inc_return(&warn_count) >= limit && limit) panic("%s: system warned too often (kernel.warn_limit is %d)", - origin, warn_limit); + origin, limit); } /** -- cgit v1.2.3-70-g09d2 From cf8016408d880afe9c5dc495af40dc2932874e77 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 22 Dec 2022 22:57:47 +0000 Subject: cfi: Fix CFI failure with KASAN When CFI_CLANG and KASAN are both enabled, LLVM doesn't generate a CFI type hash for asan.module_ctor functions in translation units where CFI is disabled, which leads to a CFI failure during boot when do_ctors calls the affected constructors: CFI failure at do_basic_setup+0x64/0x90 (target: asan.module_ctor+0x0/0x28; expected type: 0xa540670c) Specifically, this happens because CFI is disabled for kernel/cfi.c. There's no reason to keep CFI disabled here anymore, so fix the failure by not filtering out CC_FLAGS_CFI for the file. Note that https://reviews.llvm.org/rG3b14862f0a96 fixed the issue where LLVM didn't emit CFI type hashes for any sanitizer constructors, but now type hashes are emitted correctly for TUs that use CFI. Link: https://github.com/ClangBuiltLinux/linux/issues/1742 Fixes: 89245600941e ("cfi: Switch to -fsanitize=kcfi") Reported-by: Mark Rutland Signed-off-by: Sami Tolvanen Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20221222225747.3538676-1-samitolvanen@google.com --- kernel/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index d754e0be1176..ebc692242b68 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -41,9 +41,6 @@ UBSAN_SANITIZE_kcov.o := n KMSAN_SANITIZE_kcov.o := n CFLAGS_kcov.o := $(call cc-option, -fno-conserve-stack) -fno-stack-protector -# Don't instrument error handlers -CFLAGS_REMOVE_cfi.o := $(CC_FLAGS_CFI) - obj-y += sched/ obj-y += locking/ obj-y += power/ -- cgit v1.2.3-70-g09d2