From patchwork Sat Mar 17 01:49:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miguel Ojeda X-Patchwork-Id: 10290603 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9341B601A0 for ; Sat, 17 Mar 2018 01:50:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 82A612912B for ; Sat, 17 Mar 2018 01:50:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 772E42911D; Sat, 17 Mar 2018 01:50:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_TVD_MIME_EPI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ED6632911D for ; Sat, 17 Mar 2018 01:50:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753144AbeCQBtv (ORCPT ); Fri, 16 Mar 2018 21:49:51 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:38536 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753097AbeCQBtt (ORCPT ); Fri, 16 Mar 2018 21:49:49 -0400 Received: by mail-qt0-f194.google.com with SMTP id n12so12837036qtl.5; Fri, 16 Mar 2018 18:49:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=UJY0460sao/cjJ6twceWK++IddQbkrBVV3bSPinncvU=; b=OB25Xi5h5p2q12cVsyNizII3TDra+1koIa3xs107gW0DnhQ08OS6Q4DNHIh0IiMj/P 8t9p98rppYc3ilXZZ8ccrIW5BbnzmNUXtBL1qq/Dl04bu4ZRt9U1BjpgJnWBrnOLAw0j J9JCXEc0b140A5FwbpLkEf7iBlfDJyJtgYRYV4W344cg0Jssx91fT/Q3x3EJkIhzPjQx d684mZDmB2egMh4MYua60hwU99oxVjVsjUF/Q94o1LavbkXVrhl/OIUSaMnUnTivZ8dU suRpsVZoTKMMgWMau3WABVyvFnumpQmGVMK8d94E8WicaPoRvZ1yKburiwuDQ7AdYe5i KbTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=UJY0460sao/cjJ6twceWK++IddQbkrBVV3bSPinncvU=; b=ZRTSIRN7QiKMJoHVLfXawcPhgawofkjufSkRCXaRgUzQfLFu0tbol6e/Uy5U1F4htF irKRX2vOO6DZ+FkKkzX0p4eM8+PQ77d7UToM4IeTrWe/Qow57XnYqT7p5EfcuZ60XZT7 YASN41im+BiRqDq7fvdD+R/8ocjeug0sJPUW+4njSb7HG73R9+X8l++VHflsOrHbLNy5 qhYRj8mXUi9l2ZqCGTl0GY0p67cJmhyGYLdJ4DTS4+sCjjMaBb8czCMn7YAKD3/DCKV+ z0p6NkW+o+dJrj+Kg2NsbdZjjIfEQtY2kAFK+dJa/CpBC7zgmH4bqtC9MbkI9/jZEXvi TvBw== X-Gm-Message-State: AElRT7FDQvcWM1h2EEl6+H/DZA7go+C9OMY+imAHQUlagTKTW0bh+A/m CLFu67+hw32q9zNKSLEeV/jeSpAz2p6phg7K/aBwOO8lX4g= X-Google-Smtp-Source: AG47ELtHBkmakZzgokBcaSWivxVRA93Hi6DjUbLlabdyN8knLpDOC9Pyh8QKaK2Urvu6SRwN+VO8D08ZLTEN1RJsrDw= X-Received: by 10.200.39.115 with SMTP id h48mr6125243qth.115.1521251388265; Fri, 16 Mar 2018 18:49:48 -0700 (PDT) MIME-Version: 1.0 Received: by 10.200.52.227 with HTTP; Fri, 16 Mar 2018 18:49:27 -0700 (PDT) In-Reply-To: References: <1521174359-46392-1-git-send-email-keescook@chromium.org> <20180316175502.GE30522@ZenIV.linux.org.uk> From: Miguel Ojeda Date: Sat, 17 Mar 2018 02:49:27 +0100 Message-ID: Subject: Re: [PATCH v5 0/2] Remove false-positive VLAs when using max() To: Linus Torvalds Cc: Al Viro , Florian Weimer , Kees Cook , Andrew Morton , Josh Poimboeuf , Rasmus Villemoes , Randy Dunlap , Ingo Molnar , David Laight , Ian Abbott , linux-input , linux-btrfs , Network Development , Linux Kernel Mailing List , Kernel Hardening Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Fri, Mar 16, 2018 at 9:14 PM, Linus Torvalds wrote: > On Fri, Mar 16, 2018 at 1:03 PM, Miguel Ojeda > wrote: >>> >>> Kees - is there some online "gcc-4.4 checker" somewhere? This does >>> seem to work with my gcc. I actually tested some of those files you >>> pointed at now. >> >> I use this one: >> >> https://godbolt.org/ > > Well, my *test* code works on that one and -Wvla -Werror. > > It does not work with gcc-4.1.x, but works with gcc-4.4.x. > > I can't seem to see the errors any way, I wonder if > __builtin_choose_expr() simply didn't exist back then. > > Odd that you can't view warnings/errors with it. > > But it's possible that it fails on more complex stuff in the kernel. > > I've done a "allmodconfig" build with that patch, and the only issue > it found was that (real) type issue in tpm_tis_core.h. Just tested your max() with a Python script I wrote yesterday to try a lot of combinations for this thing. Your version gives some warnings in some cases, like: warning: signed and unsigned type in conditional expression [-Wsign-compare] #define __cmp(a,b,op) ((a)op(b)?(a):(b)) warning: comparison between signed and unsigned integer expressions [-Wsign-compare] #define const_max(a,b) __careful_cmp(a,b,>) warning: comparison of distinct pointer types lacks a cast (!!(sizeof((typeof(a)*)1==(typeof(b)*)1))) But it fails on something like (with warnings): int a[const_max(-30, 60u)]; Sorry... :-( Has anyone taken a look at the last one I sent? Patch attached with the draft changes on the kernel. It compiles fine the cases Kees cleaned up in the other patch, but also works without a explicit type, for mixed types, and for both positive and negative values. Cheers, Miguel diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 3fd291503576..f83658a4f15d 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -819,6 +819,49 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } __UNIQUE_ID(max1_), __UNIQUE_ID(max2_), \ x, y) +size_t __error_not_const_arg(void) \ +__compiletime_error("const_max() used with non-compile-time constant arg"); +size_t __error_too_big(void) \ +__compiletime_error("const_max() used with an arg too big"); + +#define INTMAXT_MAX LLONG_MAX +typedef int64_t intmax_t; + +#define const_cmp(x, y, op) \ + __builtin_choose_expr( \ + !__builtin_constant_p(x) || !__builtin_constant_p(y), \ + __error_not_const_arg(), \ + __builtin_choose_expr( \ + (x) > INTMAXT_MAX || (y) > INTMAXT_MAX, \ + __error_too_big(), \ + __builtin_choose_expr( \ + (intmax_t)(x) op (intmax_t)(y), \ + (x), \ + (y) \ + ) \ + ) \ + ) + +/** + * const_min - returns minimum of two compile-time constant values + * @x: first compile-time constant value + * @y: second compile-time constant value + * + * The result has the type of the winner of the comparison. Works for any + * value up to LLONG_MAX. + */ +#define const_min(x, y) const_cmp((x), (y), <=) + +/** + * const_max - returns maximum of two compile-time constant values + * @x: first compile-time constant value + * @y: second compile-time constant value + * + * The result has the type of the winner of the comparison. Works for any + * value up to LLONG_MAX. + */ +#define const_max(x, y) const_cmp((x), (y), >=) + /** * min3 - return minimum of three values * @x: first value