From: Greg Kroah-Hartman Date: Sun, 22 Jan 2023 13:54:13 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v4.14.304~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1e445087b1aa17579de767d9a34bcfe76af5e24;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: docs-fix-path-paste-o-for-sys-kernel-warn_count.patch exit-allow-oops_limit-to-be-disabled.patch exit-expose-oops_count-to-sysfs.patch exit-put-an-upper-limit-on-how-often-we-can-oops.patch exit-use-read_once-for-all-oops-warn-limit-reads.patch panic-consolidate-open-coded-panic_on_warn-checks.patch panic-expose-warn_count-to-sysfs.patch panic-introduce-warn_limit.patch panic-separate-sysctl-logic-from-config_smp.patch --- diff --git a/queue-6.1/docs-fix-path-paste-o-for-sys-kernel-warn_count.patch b/queue-6.1/docs-fix-path-paste-o-for-sys-kernel-warn_count.patch new file mode 100644 index 00000000000..59a8739d7a1 --- /dev/null +++ b/queue-6.1/docs-fix-path-paste-o-for-sys-kernel-warn_count.patch @@ -0,0 +1,36 @@ +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 + +From: Kees Cook + +commit 00dd027f721e0458418f7750d8a5a664ed3e5994 upstream. + +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 +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/ABI/testing/sysfs-kernel-warn_count | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- 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 diff --git a/queue-6.1/exit-allow-oops_limit-to-be-disabled.patch b/queue-6.1/exit-allow-oops_limit-to-be-disabled.patch new file mode 100644 index 00000000000..d4a4ad557da --- /dev/null +++ b/queue-6.1/exit-allow-oops_limit-to-be-disabled.patch @@ -0,0 +1,54 @@ +From de92f65719cd672f4b48397540b9f9eff67eca40 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Fri, 2 Dec 2022 12:59:11 -0800 +Subject: exit: Allow oops_limit to be disabled + +From: Kees Cook + +commit de92f65719cd672f4b48397540b9f9eff67eca40 upstream. + +In preparation for keeping oops_limit logic in sync with warn_limit, +have oops_limit == 0 disable checking the Oops counter. + +Cc: Jann Horn +Cc: Jonathan Corbet +Cc: Andrew Morton +Cc: Baolin Wang +Cc: "Jason A. Donenfeld" +Cc: Eric Biggers +Cc: Huang Ying +Cc: "Eric W. Biederman" +Cc: Arnd Bergmann +Cc: linux-doc@vger.kernel.org +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/admin-guide/sysctl/kernel.rst | 5 +++-- + kernel/exit.c | 2 +- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- a/Documentation/admin-guide/sysctl/kernel.rst ++++ b/Documentation/admin-guide/sysctl/kernel.rst +@@ -671,8 +671,9 @@ oops_limit + ========== + + Number of kernel oopses after which the kernel should panic when +-``panic_on_oops`` is not set. Setting this to 0 or 1 has the same effect +-as setting ``panic_on_oops=1``. ++``panic_on_oops`` is not set. Setting this to 0 disables checking ++the count. Setting this to 1 has the same effect as setting ++``panic_on_oops=1``. The default value is 10000. + + + osrelease, ostype & version +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -954,7 +954,7 @@ 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)) ++ if (atomic_inc_return(&oops_count) >= READ_ONCE(oops_limit) && oops_limit) + panic("Oopsed too often (kernel.oops_limit is %d)", oops_limit); + + /* diff --git a/queue-6.1/exit-expose-oops_count-to-sysfs.patch b/queue-6.1/exit-expose-oops_count-to-sysfs.patch new file mode 100644 index 00000000000..d6581667052 --- /dev/null +++ b/queue-6.1/exit-expose-oops_count-to-sysfs.patch @@ -0,0 +1,90 @@ +From 9db89b41117024f80b38b15954017fb293133364 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 17 Nov 2022 15:43:23 -0800 +Subject: exit: Expose "oops_count" to sysfs + +From: Kees Cook + +commit 9db89b41117024f80b38b15954017fb293133364 upstream. + +Since Oops count is now tracked and is a fairly interesting signal, add +the entry /sys/kernel/oops_count to expose it to userspace. + +Cc: "Eric W. Biederman" +Cc: Jann Horn +Cc: Arnd Bergmann +Reviewed-by: Luis Chamberlain +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221117234328.594699-3-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/ABI/testing/sysfs-kernel-oops_count | 6 ++++++ + MAINTAINERS | 1 + + kernel/exit.c | 22 ++++++++++++++++++++-- + 3 files changed, 27 insertions(+), 2 deletions(-) + create mode 100644 Documentation/ABI/testing/sysfs-kernel-oops_count + +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-kernel-oops_count +@@ -0,0 +1,6 @@ ++What: /sys/kernel/oops_count ++Date: November 2022 ++KernelVersion: 6.2.0 ++Contact: Linux Kernel Hardening List ++Description: ++ Shows how many times the system has Oopsed since last boot. +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -11112,6 +11112,7 @@ M: Kees Cook + L: linux-hardening@vger.kernel.org + S: Supported + T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening ++F: Documentation/ABI/testing/sysfs-kernel-oops_count + F: include/linux/overflow.h + F: include/linux/randomize_kstack.h + F: mm/usercopy.c +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -67,6 +67,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -99,6 +100,25 @@ static __init int kernel_exit_sysctls_in + late_initcall(kernel_exit_sysctls_init); + #endif + ++static atomic_t oops_count = ATOMIC_INIT(0); ++ ++#ifdef CONFIG_SYSFS ++static ssize_t oops_count_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *page) ++{ ++ return sysfs_emit(page, "%d\n", atomic_read(&oops_count)); ++} ++ ++static struct kobj_attribute oops_count_attr = __ATTR_RO(oops_count); ++ ++static __init int kernel_exit_sysfs_init(void) ++{ ++ sysfs_add_file_to_group(kernel_kobj, &oops_count_attr.attr, NULL); ++ return 0; ++} ++late_initcall(kernel_exit_sysfs_init); ++#endif ++ + static void __unhash_process(struct task_struct *p, bool group_dead) + { + nr_threads--; +@@ -901,8 +921,6 @@ void __noreturn do_exit(long code) + + void __noreturn make_task_dead(int signr) + { +- static atomic_t oops_count = ATOMIC_INIT(0); +- + /* + * Take the task off the cpu after something catastrophic has + * happened. diff --git a/queue-6.1/exit-put-an-upper-limit-on-how-often-we-can-oops.patch b/queue-6.1/exit-put-an-upper-limit-on-how-often-we-can-oops.patch new file mode 100644 index 00000000000..e2da7f823cf --- /dev/null +++ b/queue-6.1/exit-put-an-upper-limit-on-how-often-we-can-oops.patch @@ -0,0 +1,141 @@ +From d4ccd54d28d3c8598e2354acc13e28c060961dbb Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Thu, 17 Nov 2022 15:43:22 -0800 +Subject: exit: Put an upper limit on how often we can oops + +From: Jann Horn + +commit d4ccd54d28d3c8598e2354acc13e28c060961dbb upstream. + +Many Linux systems are configured to not panic on oops; but allowing an +attacker to oops the system **really** often can make even bugs that look +completely unexploitable exploitable (like NULL dereferences and such) if +each crash elevates a refcount by one or a lock is taken in read mode, and +this causes a counter to eventually overflow. + +The most interesting counters for this are 32 bits wide (like open-coded +refcounts that don't use refcount_t). (The ldsem reader count on 32-bit +platforms is just 16 bits, but probably nobody cares about 32-bit platforms +that much nowadays.) + +So let's panic the system if the kernel is constantly oopsing. + +The speed of oopsing 2^32 times probably depends on several factors, like +how long the stack trace is and which unwinder you're using; an empirically +important one is whether your console is showing a graphical environment or +a text console that oopses will be printed to. +In a quick single-threaded benchmark, it looks like oopsing in a vfork() +child with a very short stack trace only takes ~510 microseconds per run +when a graphical console is active; but switching to a text console that +oopses are printed to slows it down around 87x, to ~45 milliseconds per +run. +(Adding more threads makes this faster, but the actual oops printing +happens under &die_lock on x86, so you can maybe speed this up by a factor +of around 2 and then any further improvement gets eaten up by lock +contention.) + +It looks like it would take around 8-12 days to overflow a 32-bit counter +with repeated oopsing on a multi-core X86 system running a graphical +environment; both me (in an X86 VM) and Seth (with a distro kernel on +normal hardware in a standard configuration) got numbers in that ballpark. + +12 days aren't *that* short on a desktop system, and you'd likely need much +longer on a typical server system (assuming that people don't run graphical +desktop environments on their servers), and this is a *very* noisy and +violent approach to exploiting the kernel; and it also seems to take orders +of magnitude longer on some machines, probably because stuff like EFI +pstore will slow it down a ton if that's active. + +Signed-off-by: Jann Horn +Link: https://lore.kernel.org/r/20221107201317.324457-1-jannh@google.com +Reviewed-by: Luis Chamberlain +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221117234328.594699-2-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/admin-guide/sysctl/kernel.rst | 8 +++++ + kernel/exit.c | 42 ++++++++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + +--- a/Documentation/admin-guide/sysctl/kernel.rst ++++ b/Documentation/admin-guide/sysctl/kernel.rst +@@ -667,6 +667,14 @@ This is the default behavior. + an oops event is detected. + + ++oops_limit ++========== ++ ++Number of kernel oopses after which the kernel should panic when ++``panic_on_oops`` is not set. Setting this to 0 or 1 has the same effect ++as setting ``panic_on_oops=1``. ++ ++ + osrelease, ostype & version + =========================== + +--- a/kernel/exit.c ++++ b/kernel/exit.c +@@ -72,6 +72,33 @@ + #include + #include + ++/* ++ * The default value should be high enough to not crash a system that randomly ++ * crashes its kernel from time to time, but low enough to at least not permit ++ * overflowing 32-bit refcounts or the ldsem writer count. ++ */ ++static unsigned int oops_limit = 10000; ++ ++#ifdef CONFIG_SYSCTL ++static struct ctl_table kern_exit_table[] = { ++ { ++ .procname = "oops_limit", ++ .data = &oops_limit, ++ .maxlen = sizeof(oops_limit), ++ .mode = 0644, ++ .proc_handler = proc_douintvec, ++ }, ++ { } ++}; ++ ++static __init int kernel_exit_sysctls_init(void) ++{ ++ register_sysctl_init("kernel", kern_exit_table); ++ return 0; ++} ++late_initcall(kernel_exit_sysctls_init); ++#endif ++ + static void __unhash_process(struct task_struct *p, bool group_dead) + { + nr_threads--; +@@ -874,6 +901,8 @@ void __noreturn do_exit(long code) + + void __noreturn make_task_dead(int signr) + { ++ static atomic_t oops_count = ATOMIC_INIT(0); ++ + /* + * Take the task off the cpu after something catastrophic has + * happened. +@@ -898,6 +927,19 @@ void __noreturn make_task_dead(int signr + } + + /* ++ * Every time the system oopses, if the oops happens while a reference ++ * to an object was held, the reference leaks. ++ * If the oops doesn't also leak memory, repeated oopsing can cause ++ * reference counters to wrap around (if they're not using refcount_t). ++ * This means that repeated oopsing can make unexploitable-looking bugs ++ * exploitable through repeated oopsing. ++ * 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)) ++ panic("Oopsed too often (kernel.oops_limit is %d)", oops_limit); ++ ++ /* + * We're taking recursive faults here in make_task_dead. Safest is to just + * leave this task alone and wait for reboot. + */ diff --git a/queue-6.1/exit-use-read_once-for-all-oops-warn-limit-reads.patch b/queue-6.1/exit-use-read_once-for-all-oops-warn-limit-reads.patch new file mode 100644 index 00000000000..e677d584fc7 --- /dev/null +++ b/queue-6.1/exit-use-read_once-for-all-oops-warn-limit-reads.patch @@ -0,0 +1,76 @@ +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 + +From: Kees Cook + +commit 7535b832c6399b5ebfc5b53af5c51dd915ee2538 upstream. + +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 +Signed-off-by: Greg Kroah-Hartman +--- + kernel/exit.c | 6 ++++-- + kernel/panic.c | 7 +++++-- + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- 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 +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -231,12 +231,15 @@ static void panic_print_sys_info(bool co + + 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/queue-6.1/panic-consolidate-open-coded-panic_on_warn-checks.patch b/queue-6.1/panic-consolidate-open-coded-panic_on_warn-checks.patch new file mode 100644 index 00000000000..47dc869086b --- /dev/null +++ b/queue-6.1/panic-consolidate-open-coded-panic_on_warn-checks.patch @@ -0,0 +1,154 @@ +From 79cc1ba7badf9e7a12af99695a557e9ce27ee967 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 17 Nov 2022 15:43:24 -0800 +Subject: panic: Consolidate open-coded panic_on_warn checks + +From: Kees Cook + +commit 79cc1ba7badf9e7a12af99695a557e9ce27ee967 upstream. + +Several run-time checkers (KASAN, UBSAN, KFENCE, KCSAN, sched) roll +their own warnings, and each check "panic_on_warn". Consolidate this +into a single function so that future instrumentation can be added in +a single location. + +Cc: Marco Elver +Cc: Dmitry Vyukov +Cc: Ingo Molnar +Cc: Peter Zijlstra +Cc: Juri Lelli +Cc: Vincent Guittot +Cc: Dietmar Eggemann +Cc: Steven Rostedt +Cc: Ben Segall +Cc: Mel Gorman +Cc: Daniel Bristot de Oliveira +Cc: Valentin Schneider +Cc: Andrey Ryabinin +Cc: Alexander Potapenko +Cc: Andrey Konovalov +Cc: Vincenzo Frascino +Cc: Andrew Morton +Cc: David Gow +Cc: tangmeng +Cc: Jann Horn +Cc: Shuah Khan +Cc: Petr Mladek +Cc: "Paul E. McKenney" +Cc: Sebastian Andrzej Siewior +Cc: "Guilherme G. Piccoli" +Cc: Tiezhu Yang +Cc: kasan-dev@googlegroups.com +Cc: linux-mm@kvack.org +Reviewed-by: Luis Chamberlain +Signed-off-by: Kees Cook +Reviewed-by: Marco Elver +Reviewed-by: Andrey Konovalov +Link: https://lore.kernel.org/r/20221117234328.594699-4-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/panic.h | 1 + + kernel/kcsan/report.c | 3 +-- + kernel/panic.c | 9 +++++++-- + kernel/sched/core.c | 3 +-- + lib/ubsan.c | 3 +-- + mm/kasan/report.c | 4 ++-- + mm/kfence/report.c | 3 +-- + 7 files changed, 14 insertions(+), 12 deletions(-) + +--- a/include/linux/panic.h ++++ b/include/linux/panic.h +@@ -11,6 +11,7 @@ extern long (*panic_blink)(int state); + __printf(1, 2) + void panic(const char *fmt, ...) __noreturn __cold; + void nmi_panic(struct pt_regs *regs, const char *msg); ++void check_panic_on_warn(const char *origin); + extern void oops_enter(void); + extern void oops_exit(void); + extern bool oops_may_print(void); +--- a/kernel/kcsan/report.c ++++ b/kernel/kcsan/report.c +@@ -492,8 +492,7 @@ static void print_report(enum kcsan_valu + dump_stack_print_info(KERN_DEFAULT); + pr_err("==================================================================\n"); + +- if (panic_on_warn) +- panic("panic_on_warn set ...\n"); ++ check_panic_on_warn("KCSAN"); + } + + static void release_report(unsigned long *flags, struct other_info *other_info) +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -201,6 +201,12 @@ static void panic_print_sys_info(bool co + ftrace_dump(DUMP_ALL); + } + ++void check_panic_on_warn(const char *origin) ++{ ++ if (panic_on_warn) ++ panic("%s: panic_on_warn set ...\n", origin); ++} ++ + /** + * panic - halt the system + * @fmt: The text string to print +@@ -619,8 +625,7 @@ void __warn(const char *file, int line, + if (regs) + show_regs(regs); + +- if (panic_on_warn) +- panic("panic_on_warn set ...\n"); ++ check_panic_on_warn("kernel"); + + if (!regs) + dump_stack(); +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -5778,8 +5778,7 @@ static noinline void __schedule_bug(stru + pr_err("Preemption disabled at:"); + print_ip_sym(KERN_ERR, preempt_disable_ip); + } +- if (panic_on_warn) +- panic("scheduling while atomic\n"); ++ check_panic_on_warn("scheduling while atomic"); + + dump_stack(); + add_taint(TAINT_WARN, LOCKDEP_STILL_OK); +--- a/lib/ubsan.c ++++ b/lib/ubsan.c +@@ -154,8 +154,7 @@ static void ubsan_epilogue(void) + + current->in_ubsan--; + +- if (panic_on_warn) +- panic("panic_on_warn set ...\n"); ++ check_panic_on_warn("UBSAN"); + } + + void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs) +--- a/mm/kasan/report.c ++++ b/mm/kasan/report.c +@@ -164,8 +164,8 @@ static void end_report(unsigned long *fl + (unsigned long)addr); + pr_err("==================================================================\n"); + spin_unlock_irqrestore(&report_lock, *flags); +- if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) +- panic("panic_on_warn set ...\n"); ++ if (!test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) ++ check_panic_on_warn("KASAN"); + if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC) + panic("kasan.fault=panic set ...\n"); + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); +--- a/mm/kfence/report.c ++++ b/mm/kfence/report.c +@@ -273,8 +273,7 @@ void kfence_report_error(unsigned long a + + lockdep_on(); + +- if (panic_on_warn) +- panic("panic_on_warn set ...\n"); ++ check_panic_on_warn("KFENCE"); + + /* We encountered a memory safety error, taint the kernel! */ + add_taint(TAINT_BAD_PAGE, LOCKDEP_STILL_OK); diff --git a/queue-6.1/panic-expose-warn_count-to-sysfs.patch b/queue-6.1/panic-expose-warn_count-to-sysfs.patch new file mode 100644 index 00000000000..611e9fe9a97 --- /dev/null +++ b/queue-6.1/panic-expose-warn_count-to-sysfs.patch @@ -0,0 +1,93 @@ +From 8b05aa26336113c4cea25f1c333ee8cd4fc212a6 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 17 Nov 2022 15:43:26 -0800 +Subject: panic: Expose "warn_count" to sysfs + +From: Kees Cook + +commit 8b05aa26336113c4cea25f1c333ee8cd4fc212a6 upstream. + +Since Warn count is now tracked and is a fairly interesting signal, add +the entry /sys/kernel/warn_count to expose it to userspace. + +Cc: Petr Mladek +Cc: Andrew Morton +Cc: tangmeng +Cc: "Guilherme G. Piccoli" +Cc: Sebastian Andrzej Siewior +Cc: Tiezhu Yang +Reviewed-by: Luis Chamberlain +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221117234328.594699-6-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/ABI/testing/sysfs-kernel-warn_count | 6 ++++++ + MAINTAINERS | 1 + + kernel/panic.c | 22 ++++++++++++++++++++-- + 3 files changed, 27 insertions(+), 2 deletions(-) + create mode 100644 Documentation/ABI/testing/sysfs-kernel-warn_count + +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-kernel-warn_count +@@ -0,0 +1,6 @@ ++What: /sys/kernel/oops_count ++Date: November 2022 ++KernelVersion: 6.2.0 ++Contact: Linux Kernel Hardening List ++Description: ++ Shows how many times the system has Warned since last boot. +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -11113,6 +11113,7 @@ L: linux-hardening@vger.kernel.org + S: Supported + T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening + F: Documentation/ABI/testing/sysfs-kernel-oops_count ++F: Documentation/ABI/testing/sysfs-kernel-warn_count + F: include/linux/overflow.h + F: include/linux/randomize_kstack.h + F: mm/usercopy.c +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -107,6 +108,25 @@ static __init int kernel_panic_sysctls_i + late_initcall(kernel_panic_sysctls_init); + #endif + ++static atomic_t warn_count = ATOMIC_INIT(0); ++ ++#ifdef CONFIG_SYSFS ++static ssize_t warn_count_show(struct kobject *kobj, struct kobj_attribute *attr, ++ char *page) ++{ ++ return sysfs_emit(page, "%d\n", atomic_read(&warn_count)); ++} ++ ++static struct kobj_attribute warn_count_attr = __ATTR_RO(warn_count); ++ ++static __init int kernel_panic_sysfs_init(void) ++{ ++ sysfs_add_file_to_group(kernel_kobj, &warn_count_attr.attr, NULL); ++ return 0; ++} ++late_initcall(kernel_panic_sysfs_init); ++#endif ++ + static long no_blink(int state) + { + return 0; +@@ -211,8 +231,6 @@ static void panic_print_sys_info(bool co + + void check_panic_on_warn(const char *origin) + { +- static atomic_t warn_count = ATOMIC_INIT(0); +- + if (panic_on_warn) + panic("%s: panic_on_warn set ...\n", origin); + diff --git a/queue-6.1/panic-introduce-warn_limit.patch b/queue-6.1/panic-introduce-warn_limit.patch new file mode 100644 index 00000000000..ee910af10b9 --- /dev/null +++ b/queue-6.1/panic-introduce-warn_limit.patch @@ -0,0 +1,91 @@ +From 9fc9e278a5c0b708eeffaf47d6eb0c82aa74ed78 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 17 Nov 2022 15:43:25 -0800 +Subject: panic: Introduce warn_limit + +From: Kees Cook + +commit 9fc9e278a5c0b708eeffaf47d6eb0c82aa74ed78 upstream. + +Like oops_limit, add warn_limit for limiting the number of warnings when +panic_on_warn is not set. + +Cc: Jonathan Corbet +Cc: Andrew Morton +Cc: Baolin Wang +Cc: "Jason A. Donenfeld" +Cc: Eric Biggers +Cc: Huang Ying +Cc: Petr Mladek +Cc: tangmeng +Cc: "Guilherme G. Piccoli" +Cc: Tiezhu Yang +Cc: Sebastian Andrzej Siewior +Cc: linux-doc@vger.kernel.org +Reviewed-by: Luis Chamberlain +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221117234328.594699-5-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/admin-guide/sysctl/kernel.rst | 10 ++++++++++ + kernel/panic.c | 14 ++++++++++++++ + 2 files changed, 24 insertions(+) + +--- a/Documentation/admin-guide/sysctl/kernel.rst ++++ b/Documentation/admin-guide/sysctl/kernel.rst +@@ -1532,6 +1532,16 @@ entry will default to 2 instead of 0. + 2 Unprivileged calls to ``bpf()`` are disabled + = ============================================================= + ++ ++warn_limit ++========== ++ ++Number of kernel warnings after which the kernel should panic when ++``panic_on_warn`` is not set. Setting this to 0 disables checking ++the warning count. Setting this to 1 has the same effect as setting ++``panic_on_warn=1``. The default value is 0. ++ ++ + watchdog + ======== + +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -58,6 +58,7 @@ bool crash_kexec_post_notifiers; + int panic_on_warn __read_mostly; + unsigned long panic_on_taint; + bool panic_on_taint_nousertaint = false; ++static unsigned int warn_limit __read_mostly; + + int panic_timeout = CONFIG_PANIC_TIMEOUT; + EXPORT_SYMBOL_GPL(panic_timeout); +@@ -88,6 +89,13 @@ static struct ctl_table kern_panic_table + .extra2 = SYSCTL_ONE, + }, + #endif ++ { ++ .procname = "warn_limit", ++ .data = &warn_limit, ++ .maxlen = sizeof(warn_limit), ++ .mode = 0644, ++ .proc_handler = proc_douintvec, ++ }, + { } + }; + +@@ -203,8 +211,14 @@ static void panic_print_sys_info(bool co + + void check_panic_on_warn(const char *origin) + { ++ static atomic_t warn_count = ATOMIC_INIT(0); ++ + if (panic_on_warn) + panic("%s: panic_on_warn set ...\n", origin); ++ ++ if (atomic_inc_return(&warn_count) >= READ_ONCE(warn_limit) && warn_limit) ++ panic("%s: system warned too often (kernel.warn_limit is %d)", ++ origin, warn_limit); + } + + /** diff --git a/queue-6.1/panic-separate-sysctl-logic-from-config_smp.patch b/queue-6.1/panic-separate-sysctl-logic-from-config_smp.patch new file mode 100644 index 00000000000..89463febd54 --- /dev/null +++ b/queue-6.1/panic-separate-sysctl-logic-from-config_smp.patch @@ -0,0 +1,47 @@ +From 9360d035a579d95d1e76c471061b9065b18a0eb1 Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Thu, 17 Nov 2022 15:43:21 -0800 +Subject: panic: Separate sysctl logic from CONFIG_SMP + +From: Kees Cook + +commit 9360d035a579d95d1e76c471061b9065b18a0eb1 upstream. + +In preparation for adding more sysctls directly in kernel/panic.c, split +CONFIG_SMP from the logic that adds sysctls. + +Cc: Petr Mladek +Cc: Andrew Morton +Cc: tangmeng +Cc: "Guilherme G. Piccoli" +Cc: Tiezhu Yang +Cc: Sebastian Andrzej Siewior +Reviewed-by: Luis Chamberlain +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20221117234328.594699-1-keescook@chromium.org +Signed-off-by: Greg Kroah-Hartman +--- + kernel/panic.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -75,8 +75,9 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list + + EXPORT_SYMBOL(panic_notifier_list); + +-#if defined(CONFIG_SMP) && defined(CONFIG_SYSCTL) ++#ifdef CONFIG_SYSCTL + static struct ctl_table kern_panic_table[] = { ++#ifdef CONFIG_SMP + { + .procname = "oops_all_cpu_backtrace", + .data = &sysctl_oops_all_cpu_backtrace, +@@ -86,6 +87,7 @@ static struct ctl_table kern_panic_table + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, ++#endif + { } + }; + diff --git a/queue-6.1/series b/queue-6.1/series index 8f6258d5056..d6b72707ce8 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -146,3 +146,12 @@ cifs-reduce-roundtrips-on-create-qinfo-requests.patch fs-ntfs3-fix-attr_punch_hole-null-pointer-derenference.patch arm64-efi-execute-runtime-services-from-a-dedicated-stack.patch efi-rt-wrapper-add-missing-include.patch +panic-separate-sysctl-logic-from-config_smp.patch +exit-put-an-upper-limit-on-how-often-we-can-oops.patch +exit-expose-oops_count-to-sysfs.patch +exit-allow-oops_limit-to-be-disabled.patch +panic-consolidate-open-coded-panic_on_warn-checks.patch +panic-introduce-warn_limit.patch +panic-expose-warn_count-to-sysfs.patch +docs-fix-path-paste-o-for-sys-kernel-warn_count.patch +exit-use-read_once-for-all-oops-warn-limit-reads.patch