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: 10290601 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 EDB83601BE for ; Sat, 17 Mar 2018 01:50:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BB1E82910A for ; Sat, 17 Mar 2018 01:50:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B985529129; Sat, 17 Mar 2018 01:50:04 +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=-4.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id D2EF92910A for ; Sat, 17 Mar 2018 01:50:02 +0000 (UTC) Received: (qmail 1645 invoked by uid 550); 17 Mar 2018 01:50:00 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 1622 invoked from network); 17 Mar 2018 01:50:00 -0000 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=RLVWZmGDvrGlrU3O+vsIMcqegBcmqcxyx+IrY54hIKuMAYQ0cd5Y4nqVFjoRvzoSjG mK0XWmVA6VinHuGnOnV/4NUouH6CW6ykX8x43nr0rsCKe6I8U5UQyqSk5FsLonQW2mhL iXEitvBoB442rdqtkVk7s/l8y0j15ljF9UxQRl7G1kI8jQFxAxDqgHaeSqrqhu3gMyKe ciaC8aUYfpBEsawcFVIBucm/bDaiAgwkaV+gwqZijOiPHhj1TDF+huO5N1P1MeGmmD2S 77w3ZDgNu/0qPgRaJxTSgqApI1rv434mWc+De2CSD1XWF7Vi+U5lFPcDTdBASnuWtD2d uUbA== X-Gm-Message-State: AElRT7FzRjqj6wpKbwz8FzbE2iOOZGXB25wjh3pJWPixMHTUK+Gd7U0+ 9mppmYQvfAbysfqvf65dXRCKH4ymoGjK25k9A/s= 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 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 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