The patch titled Subject: kernel.h: skip single-eval logic on literals in min()/max() has been removed from the -mm tree. Its filename was kernelh-skip-single-eval-logic-on-literals-in-min-max.patch This patch was dropped because it had testing failures ------------------------------------------------------ From: Kees Cook <keescook@xxxxxxxxxxxx> Subject: kernel.h: skip single-eval logic on literals in min()/max() When max() is used in stack array size calculations from literal values (e.g. "char foo[max(sizeof(struct1), sizeof(struct2))]", the compiler thinks this is a dynamic calculation due to the single-eval logic, which is not needed in the literal case. This change removes several accidental stack VLAs from an x86 allmodconfig build: $ diff -u before.txt after.txt | grep ^- -drivers/input/touchscreen/cyttsp4_core.c:871:2: warning: ISO C90 forbids variable length array `ids' [-Wvla] -fs/btrfs/tree-checker.c:344:4: warning: ISO C90 forbids variable length array `namebuf' [-Wvla] -lib/vsprintf.c:747:2: warning: ISO C90 forbids variable length array `sym' [-Wvla] -net/ipv4/proc.c:403:2: warning: ISO C90 forbids variable length array `buff' [-Wvla] -net/ipv6/proc.c:198:2: warning: ISO C90 forbids variable length array `buff' [-Wvla] -net/ipv6/proc.c:218:2: warning: ISO C90 forbids variable length array `buff64' [-Wvla] Based on an earlier patch from Josh Poimboeuf. [keescook@xxxxxxxxxxxx: v2] Link: http://lkml.kernel.org/r/20180308233758.GA22120@beast [keescook@xxxxxxxxxxxx: drop __builtin_types_compatible_p()] Link: http://lkml.kernel.org/r/20180309200536.GA5670@beast Link: http://lkml.kernel.org/r/20180308214045.GA6787@beast Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> Reviewed-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Josh Poimboeuf <jpoimboe@xxxxxxxxxx> Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx> Cc: "Gustavo A. R. Silva" <gustavo@xxxxxxxxxxxxxx> Cc: "Tobin C. Harding" <me@xxxxxxxx> Cc: Steven Rostedt <rostedt@xxxxxxxxxxx> Cc: Jonathan Corbet <corbet@xxxxxxx> Cc: Chris Mason <clm@xxxxxx> Cc: Josef Bacik <jbacik@xxxxxx> Cc: David Sterba <dsterba@xxxxxxxx> Cc: "David S. Miller" <davem@xxxxxxxxxxxxx> Cc: Alexey Kuznetsov <kuznet@xxxxxxxxxxxxx> Cc: Hideaki YOSHIFUJI <yoshfuji@xxxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Masahiro Yamada <yamada.masahiro@xxxxxxxxxxxxx> Cc: Borislav Petkov <bp@xxxxxxx> Cc: Randy Dunlap <rdunlap@xxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@xxxxxxxxx> Cc: Petr Mladek <pmladek@xxxxxxxx> Cc: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Cc: Pantelis Antoniou <pantelis.antoniou@xxxxxxxxxxxx Cc: Ian Campbell <ijc@xxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/kernel.h | 48 ++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff -puN include/linux/kernel.h~kernelh-skip-single-eval-logic-on-literals-in-min-max include/linux/kernel.h --- a/include/linux/kernel.h~kernelh-skip-single-eval-logic-on-literals-in-min-max +++ a/include/linux/kernel.h @@ -790,37 +790,55 @@ static inline void ftrace_dump(enum ftra * strict type-checking.. See the * "unnecessary" pointer comparison. */ -#define __min(t1, t2, min1, min2, x, y) ({ \ +#define __single_eval_min(t1, t2, min1, min2, x, y) ({ \ t1 min1 = (x); \ t2 min2 = (y); \ (void) (&min1 == &min2); \ min1 < min2 ? min1 : min2; }) +/* + * In the case of compile-time constant values, there is no need to do + * the double-evaluation protection, so the raw comparison can be made. + * This allows min()/max() to be used in stack array allocations and + * avoid the compiler thinking it is a dynamic value leading to an + * accidental VLA. + */ +#define __min(t1, t2, x, y) \ + __builtin_choose_expr(__builtin_constant_p(x) && \ + __builtin_constant_p(y), \ + (t1)(x) < (t2)(y) ? (t1)(x) : (t2)(y), \ + __single_eval_min(t1, t2, \ + __UNIQUE_ID(min1_), \ + __UNIQUE_ID(min2_), \ + x, y)) + /** * min - return minimum of two values of the same or compatible types * @x: first value * @y: second value */ -#define min(x, y) \ - __min(typeof(x), typeof(y), \ - __UNIQUE_ID(min1_), __UNIQUE_ID(min2_), \ - x, y) +#define min(x, y) __min(typeof(x), typeof(y), x, y) -#define __max(t1, t2, max1, max2, x, y) ({ \ +#define __single_eval_max(t1, t2, max1, max2, x, y) ({ \ t1 max1 = (x); \ t2 max2 = (y); \ (void) (&max1 == &max2); \ max1 > max2 ? max1 : max2; }) +#define __max(t1, t2, x, y) \ + __builtin_choose_expr(__builtin_constant_p(x) && \ + __builtin_constant_p(y), \ + (t1)(x) > (t2)(y) ? (t1)(x) : (t2)(y), \ + __single_eval_max(t1, t2, \ + __UNIQUE_ID(max1_), \ + __UNIQUE_ID(max2_), \ + x, y)) /** * max - return maximum of two values of the same or compatible types * @x: first value * @y: second value */ -#define max(x, y) \ - __max(typeof(x), typeof(y), \ - __UNIQUE_ID(max1_), __UNIQUE_ID(max2_), \ - x, y) +#define max(x, y) __max(typeof(x), typeof(y), x, y) /** * min3 - return minimum of three values @@ -872,10 +890,7 @@ static inline void ftrace_dump(enum ftra * @x: first value * @y: second value */ -#define min_t(type, x, y) \ - __min(type, type, \ - __UNIQUE_ID(min1_), __UNIQUE_ID(min2_), \ - x, y) +#define min_t(type, x, y) __min(type, type, x, y) /** * max_t - return maximum of two values, using the specified type @@ -883,10 +898,7 @@ static inline void ftrace_dump(enum ftra * @x: first value * @y: second value */ -#define max_t(type, x, y) \ - __max(type, type, \ - __UNIQUE_ID(min1_), __UNIQUE_ID(min2_), \ - x, y) +#define max_t(type, x, y) __max(type, type, x, y) /** * clamp_t - return a value clamped to a given range using a given type _ Patches currently in -mm which might be from keescook@xxxxxxxxxxxx are taint-convert-to-indexed-initialization.patch taint-consolidate-documentation.patch taint-add-taint-for-randstruct.patch test_bitmap-do-not-accidentally-use-stack-vla.patch fork-unconditionally-clear-stack-on-fork.patch exec-pass-stack-rlimit-into-mm-layout-functions.patch exec-introduce-finalize_exec-before-start_thread.patch exec-pin-stack-limit-during-exec.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html