From patchwork Fri Mar 16 04:25:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 10286379 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 4C9E9601BE for ; Fri, 16 Mar 2018 04:26:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 457F728D24 for ; Fri, 16 Mar 2018 04:26:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 38D0C28D2E; Fri, 16 Mar 2018 04:26:28 +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_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 C799028D24 for ; Fri, 16 Mar 2018 04:26:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751736AbeCPE0K (ORCPT ); Fri, 16 Mar 2018 00:26:10 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:41810 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750826AbeCPE0G (ORCPT ); Fri, 16 Mar 2018 00:26:06 -0400 Received: by mail-pf0-f196.google.com with SMTP id f80so3718650pfa.8 for ; Thu, 15 Mar 2018 21:26:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eNbhngV0sTnspfoX+8GgHF02vVphrEUurDkfyZCcFFU=; b=JQDZayrv1B0bFOrineuoV3C69YHZtKa1BTIzjBS36C75DqlC8WROOFkZFKMSBsUNcw nYQDP4XG1nEkr64TUt4gndcSBEloCW0en92UPnaaXn6cH0QyJE4amtBsccuwoiNnQe8/ Jca1icVgiWsn8C6nlF9toPPZ2duAuVvhb1Oe0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eNbhngV0sTnspfoX+8GgHF02vVphrEUurDkfyZCcFFU=; b=r4hjB7pv4+XsEqYNltepvA7CWQQTaMciZAWSur2G/WJXBpVMqgezbCmyoebgwXY3FH pHvsUmVYVHXlw+x6Elv+VEguAXDCxStbllR9bNPh74ijbRKm1kjVNhEJIGn+pcJsjwK8 DzHJeK7oLrBQVEgXITKX0GJ0JIOSyagLIwjjXg9MVQeYtlhU+qejrWIVWxqKx1mhG4vA tgm7SrIqJ13rGP2HgFKSo8EpgBdz/Fj5y7hp23lAemzXGhkuqdh3cd8F85e6VAppqGeh RXBHuDs0JzjJKJenWh/7eNZo7oaAaLfcIcBK8hMsI+Rdgw9h77Cq7r5N3M7lZfBg22zg 2Omw== X-Gm-Message-State: AElRT7FpXTnj61fqNJeLddMBVHkeMaoWd0Hu+Lx5DwCFZR3MKJq0hp55 W12kcZ/87a5Y7brrGUsL5pTcsg== X-Google-Smtp-Source: AG47ELvfRtErUV0+GPtQJOy+8qquv5l2SeENkFF214yWZtE8hj3fALz5r57H4ASXqbiJq/hL7LaGhg== X-Received: by 10.99.120.138 with SMTP id t132mr342233pgc.280.1521174365952; Thu, 15 Mar 2018 21:26:05 -0700 (PDT) Received: from www.outflux.net (173-164-112-133-Oregon.hfc.comcastbusiness.net. [173.164.112.133]) by smtp.gmail.com with ESMTPSA id z15sm10809740pgr.68.2018.03.15.21.26.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Mar 2018 21:26:03 -0700 (PDT) From: Kees Cook To: Andrew Morton Cc: Kees Cook , Linus Torvalds , Josh Poimboeuf , Rasmus Villemoes , Randy Dunlap , Miguel Ojeda , Ingo Molnar , David Laight , Ian Abbott , linux-input@vger.kernel.org, linux-btrfs@vger.kernel.org, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Subject: [PATCH v5 1/2] kernel.h: Introduce const_max_t() for VLA removal Date: Thu, 15 Mar 2018 21:25:58 -0700 Message-Id: <1521174359-46392-2-git-send-email-keescook@chromium.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521174359-46392-1-git-send-email-keescook@chromium.org> References: <1521174359-46392-1-git-send-email-keescook@chromium.org> MIME-Version: 1.0 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 In the effort to remove all VLAs from the kernel[1], it is desirable to build with -Wvla. However, this warning is overly pessimistic, in that it is only happy with stack array sizes that are declared as constant expressions, and not constant values. One case of this is the evaluation of the max() macro which, due to its construction, ends up converting constant expression arguments into a constant value result. Attempts to adjust the behavior of max() ran afoul of version-dependent compiler behavior[2]. To work around this and still gain -Wvla coverage, this patch introduces a new macro, const_max_t(), for use in these cases of stack array size declaration, where the constant expressions are retained. Since this means losing the double-evaluation protections of the max() macro, this macro is designed to explicitly fail if used on non-constant arguments. Older compilers will fail with the unhelpful message: error: first argument to ‘__builtin_choose_expr’ not a constant Newer compilers will fail with a hopefully more helpful message: error: call to ‘__error_non_const_arg’ declared with attribute error: const_max_t() used with non-constant expression To gain the ability to compare differing types, the desired type must be explicitly declared, as with the existing max_t() macro. This is needed when comparing different enum types and to allow things like: int foo[const_max_t(size_t, 6, sizeof(something))]; [1] https://lkml.org/lkml/2018/3/7/621 [2] https://lkml.org/lkml/2018/3/10/170 Signed-off-by: Kees Cook --- include/linux/kernel.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 3fd291503576..e14531781568 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -820,6 +820,25 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } x, y) /** + * const_max_t - return maximum of two compile-time constant expressions + * @type: type used for evaluation + * @x: first compile-time constant expression + * @y: second compile-time constant expression + * + * This has no multi-evaluation defenses, and must only ever be used with + * compile-time constant expressions (for example when calculating a stack + * array size). + */ +size_t __error_non_const_arg(void) \ +__compiletime_error("const_max_t() used with non-constant expression"); +#define const_max_t(type, x, y) \ + __builtin_choose_expr(__builtin_constant_p(x) && \ + __builtin_constant_p(y), \ + (type)(x) > (type)(y) ? \ + (type)(x) : (type)(y), \ + __error_non_const_arg()) + +/** * min3 - return minimum of three values * @x: first value * @y: second value