Received: by 10.223.185.116 with SMTP id b49csp138068wrg; Thu, 8 Mar 2018 14:21:24 -0800 (PST) X-Google-Smtp-Source: AG47ELsGv815R5YnKAQkaLZQhE8RdJeX6h9fE42JBcPs2ixOHARr7u8QPIMzijoZLu9Hm0P8b9rq X-Received: by 2002:a17:902:ab84:: with SMTP id f4-v6mr25768824plr.239.1520547684413; Thu, 08 Mar 2018 14:21:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520547684; cv=none; d=google.com; s=arc-20160816; b=vQ9dh0RnGUE+nFxXnCLWkCSjxI3r5/JtTJuR59t4OFEu7Yu9q9nttnjDdZ7Kz0e4/X +7b2bfrUsSvlxxdF4M5Fqd+Z+r0uglMbjoqFpa0jB9pFZ93+c1fJ2dmdXanEPvfKt49F JjxzWSe7ZPEBbwqFxexDsGV2f7S+edhsFn/jEv5P/tB3N6046bhq4h5E+uYWLJeTXlA5 6YPq11x8HCtH0hRbCmMG1JgO0WRy50rh61MzRLq/uqubbkRR+W98lZIQiOnkhU07VXtN t49NtSnI11DaPaMjHjyllorkEmQ9LwpjqfEHmP31F5EDZoBiMeH+O6kbkg1dWCmbimCN f7AQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date :arc-authentication-results; bh=1nitwgJDn30fyBj8c1OO4GWbGNrssL4l1RkM3IULTVk=; b=x/JPkIlMPINCLEYvSoiNXLSY+jYGme+PgD4s0gA6bNj6/suUmE8w2Mn1u3SOcTvNfD 0I3OpfCXBmdURMtObl6+XlBqqLj/a+0UTlf6zh/RA7lch6i8tBdWdXNSpzBam78X1Wtq MZ45FZyEJjfIuxJy0iU7ee01K3Pb3XoWywYhQ+IYzVGqsUd8Ng5NdiwcxJrCfHCDIqqp Qbu1B+pByw4fxtV1mSsqiOy92gAbc+BHiFe46OhgAp9V/g/sCNlh2aUntsXxi5qX3QHG Cvglu4o45mSYkVGWINR1Sa3YeKGRgufpNh+DpBYkBG+89q1j9PAayNd2DW8vFBMmf/MC /ENQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u193si13675793pgc.352.2018.03.08.14.21.09; Thu, 08 Mar 2018 14:21:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751224AbeCHWSj (ORCPT + 99 others); Thu, 8 Mar 2018 17:18:39 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:47380 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750953AbeCHWSh (ORCPT ); Thu, 8 Mar 2018 17:18:37 -0500 Received: from localhost.localdomain (c-24-4-125-7.hsd1.ca.comcast.net [24.4.125.7]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 5273C92B; Thu, 8 Mar 2018 22:18:34 +0000 (UTC) Date: Thu, 8 Mar 2018 14:18:33 -0800 From: Andrew Morton To: Kees Cook Cc: Josh Poimboeuf , Rasmus Villemoes , "Gustavo A. R. Silva" , "Tobin C. Harding" , rostedt@goodmis.org, corbet@lwn.net, Chris Mason , Josef Bacik , David Sterba , "David S. Miller" , Alexey Kuznetsov , Hideaki YOSHIFUJI , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Masahiro Yamada , Borislav Petkov , Randy Dunlap , Ian Abbott , Sergey Senozhatsky , Petr Mladek , Andy Shevchenko , Pantelis Antoniou , linux-btrfs@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Subject: Re: [PATCH] kernel.h: Skip single-eval logic on literals in min()/max() Message-Id: <20180308141833.3fb57913bceae38f18db2bf1@linux-foundation.org> In-Reply-To: <20180308214045.GA6787@beast> References: <20180308214045.GA6787@beast> X-Mailer: Sylpheed 3.5.1 (GTK+ 2.24.31; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 8 Mar 2018 13:40:45 -0800 Kees Cook wrote: > 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. > > ... > > --- a/include/linux/kernel.h > +++ b/include/linux/kernel.h > @@ -787,37 +787,57 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } > * 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 builtin 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) && \ > + __builtin_types_compatible_p(t1, t2), \ > + (t1)(x) < (t2)(y) ? (t1)(x) : (t2)(y), \ > + __single_eval_min(t1, t2, \ > + __UNIQUE_ID(max1_), \ > + __UNIQUE_ID(max2_), \ > + x, y)) > + Holy crap. I suppose gcc will one day be fixed and we won't need this. Is there a good reason to convert min()? Surely nobody will be using min to dimension an array - always max? Just for symmetry, I guess.