summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-12-23 12:00:24 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2022-12-23 12:00:24 -0800
commit51094a24b85e29138b7fa82ef1e1b4fe19c90046 (patch)
treef1ce01b4d655b191a6b96f7caae68976c5e95867
parentedb23125fd4a79003012bc619d2c604da922865e (diff)
parentcf8016408d880afe9c5dc495af40dc2932874e77 (diff)
Merge tag 'hardening-v6.2-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull kernel hardening fixes from Kees Cook: - Fix CFI failure with KASAN (Sami Tolvanen) - Fix LKDTM + CFI under GCC 7 and 8 (Kristina Martsenko) - Limit CONFIG_ZERO_CALL_USED_REGS to Clang > 15.0.6 (Nathan Chancellor) - Ignore "contents" argument in LoadPin's LSM hook handling - Fix paste-o in /sys/kernel/warn_count API docs - Use READ_ONCE() consistently for oops/warn limit reading * tag 'hardening-v6.2-rc1-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: cfi: Fix CFI failure with KASAN exit: Use READ_ONCE() for all oops/warn limit reads security: Restrict CONFIG_ZERO_CALL_USED_REGS to gcc or clang > 15.0.6 lkdtm: cfi: Make PAC test work with GCC 7 and 8 docs: Fix path paste-o for /sys/kernel/warn_count LoadPin: Ignore the "contents" argument of the LSM hooks
-rw-r--r--Documentation/ABI/testing/sysfs-kernel-warn_count2
-rw-r--r--drivers/misc/lkdtm/cfi.c6
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/exit.c6
-rw-r--r--kernel/panic.c7
-rw-r--r--security/Kconfig.hardening3
-rw-r--r--security/loadpin/loadpin.c30
7 files changed, 36 insertions, 21 deletions
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 <linux-hardening@vger.kernel.org>
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
diff --git a/kernel/Makefile b/kernel/Makefile
index e7fc37a68069..10ef068f598d 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/
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 326d91505f04..463c9295bc28 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -232,12 +232,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);
}
/**
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"
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 = {