| From 1e7b660661016ce689f41e0eb07968ac6c47186b Mon Sep 17 00:00:00 2001 |
| From: Kees Cook <keescook@chromium.org> |
| Date: Wed, 25 Sep 2019 16:47:52 -0700 |
| Subject: [PATCH] bug: refactor away warn_slowpath_fmt_taint() |
| |
| commit ee8711336c51708382627ebcaee5f2122b77dfef upstream. |
| |
| Patch series "Clean up WARN() "cut here" handling", v2. |
| |
| Christophe Leroy noticed that the fix for missing "cut here" in the WARN() |
| case was adding explicit printk() calls instead of teaching the exception |
| handler to add it. This refactors the bug/warn infrastructure to pass |
| this information as a new BUGFLAG. |
| |
| Longer details repeated from the last patch in the series: |
| |
| bug: move WARN_ON() "cut here" into exception handler |
| |
| The original cleanup of "cut here" missed the WARN_ON() case (that does |
| not have a printk message), which was fixed recently by adding an explicit |
| printk of "cut here". This had the downside of adding a printk() to every |
| WARN_ON() caller, which reduces the utility of using an instruction |
| exception to streamline the resulting code. By making this a new BUGFLAG, |
| all of these can be removed and "cut here" can be handled by the exception |
| handler. |
| |
| This was very pronounced on PowerPC, but the effect can be seen on x86 as |
| well. The resulting text size of a defconfig build shows some small |
| savings from this patch: |
| |
| text data bss dec hex filename |
| 19691167 5134320 1646664 26472151 193eed7 vmlinux.before |
| 19676362 5134260 1663048 26473670 193f4c6 vmlinux.after |
| |
| This change also opens the door for creating something like BUG_MSG(), |
| where a custom printk() before issuing BUG(), without confusing the "cut |
| here" line. |
| |
| This patch (of 7): |
| |
| There's no reason to have specialized helpers for passing the warn taint |
| down to __warn(). Consolidate and refactor helper macros, removing |
| __WARN_printf() and warn_slowpath_fmt_taint(). |
| |
| Link: http://lkml.kernel.org/r/20190819234111.9019-2-keescook@chromium.org |
| Signed-off-by: Kees Cook <keescook@chromium.org> |
| Cc: Christophe Leroy <christophe.leroy@c-s.fr> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Christophe Leroy <christophe.leroy@c-s.fr> |
| Cc: Drew Davenport <ddavenport@chromium.org> |
| Cc: Arnd Bergmann <arnd@arndb.de> |
| Cc: "Steven Rostedt (VMware)" <rostedt@goodmis.org> |
| Cc: Feng Tang <feng.tang@intel.com> |
| Cc: Petr Mladek <pmladek@suse.com> |
| Cc: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> |
| Cc: Borislav Petkov <bp@suse.de> |
| Cc: YueHaibing <yuehaibing@huawei.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h |
| index 7357a3c942a0..c3a9c16a2b69 100644 |
| --- a/include/asm-generic/bug.h |
| +++ b/include/asm-generic/bug.h |
| @@ -90,24 +90,19 @@ struct bug_entry { |
| * Use the versions with printk format strings to provide better diagnostics. |
| */ |
| #ifndef __WARN_TAINT |
| -extern __printf(3, 4) |
| -void warn_slowpath_fmt(const char *file, const int line, |
| - const char *fmt, ...); |
| extern __printf(4, 5) |
| -void warn_slowpath_fmt_taint(const char *file, const int line, unsigned taint, |
| - const char *fmt, ...); |
| +void warn_slowpath_fmt(const char *file, const int line, unsigned taint, |
| + const char *fmt, ...); |
| extern void warn_slowpath_null(const char *file, const int line); |
| #define WANT_WARN_ON_SLOWPATH |
| #define __WARN() warn_slowpath_null(__FILE__, __LINE__) |
| -#define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg) |
| #define __WARN_printf_taint(taint, arg...) \ |
| - warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg) |
| + warn_slowpath_fmt(__FILE__, __LINE__, taint, arg) |
| #else |
| extern __printf(1, 2) void __warn_printk(const char *fmt, ...); |
| #define __WARN() do { \ |
| printk(KERN_WARNING CUT_HERE); __WARN_TAINT(TAINT_WARN); \ |
| } while (0) |
| -#define __WARN_printf(arg...) __WARN_printf_taint(TAINT_WARN, arg) |
| #define __WARN_printf_taint(taint, arg...) \ |
| do { __warn_printk(arg); __WARN_TAINT(taint); } while (0) |
| #endif |
| @@ -132,7 +127,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint, |
| #define WARN(condition, format...) ({ \ |
| int __ret_warn_on = !!(condition); \ |
| if (unlikely(__ret_warn_on)) \ |
| - __WARN_printf(format); \ |
| + __WARN_printf_taint(TAINT_WARN, format); \ |
| unlikely(__ret_warn_on); \ |
| }) |
| #endif |
| diff --git a/kernel/panic.c b/kernel/panic.c |
| index 3406a7a31449..d26e2170331f 100644 |
| --- a/kernel/panic.c |
| +++ b/kernel/panic.c |
| @@ -593,20 +593,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, |
| } |
| |
| #ifdef WANT_WARN_ON_SLOWPATH |
| -void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) |
| -{ |
| - struct warn_args args; |
| - |
| - args.fmt = fmt; |
| - va_start(args.args, fmt); |
| - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, |
| - &args); |
| - va_end(args.args); |
| -} |
| -EXPORT_SYMBOL(warn_slowpath_fmt); |
| - |
| -void warn_slowpath_fmt_taint(const char *file, int line, |
| - unsigned taint, const char *fmt, ...) |
| +void warn_slowpath_fmt(const char *file, int line, unsigned taint, |
| + const char *fmt, ...) |
| { |
| struct warn_args args; |
| |
| @@ -615,7 +603,7 @@ void warn_slowpath_fmt_taint(const char *file, int line, |
| __warn(file, line, __builtin_return_address(0), taint, NULL, &args); |
| va_end(args.args); |
| } |
| -EXPORT_SYMBOL(warn_slowpath_fmt_taint); |
| +EXPORT_SYMBOL(warn_slowpath_fmt); |
| |
| void warn_slowpath_null(const char *file, int line) |
| { |
| -- |
| 2.7.4 |
| |