From patchwork Thu Mar 15 19:47:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 10285695 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 6C04B60291 for ; Thu, 15 Mar 2018 19:47:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 52D7128B60 for ; Thu, 15 Mar 2018 19:47:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 46F8028BEA; Thu, 15 Mar 2018 19:47:57 +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=ham 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 AC84428B60 for ; Thu, 15 Mar 2018 19:47:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752168AbeCOTrz (ORCPT ); Thu, 15 Mar 2018 15:47:55 -0400 Received: from mail-pl0-f68.google.com ([209.85.160.68]:35495 "EHLO mail-pl0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751729AbeCOTrx (ORCPT ); Thu, 15 Mar 2018 15:47:53 -0400 Received: by mail-pl0-f68.google.com with SMTP id p9-v6so1877105pls.2 for ; Thu, 15 Mar 2018 12:47:53 -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=lj4zQ/k/yu01ARgkyBeTOKuSoVDiR5D4J5KvwtDC7qI=; b=KKX74YJSzyqvgg9URplHd7ngxPe+lRa8UxeXSnBDv7rQEKTru1A8hV6OvlLmlchbGD bZhhaX278PRe1Hq3EI9/itDha0K+dyDFM3e0nqfLEALGPrf0GsngOshKwyIJXTaUuRX9 3XYxZdi3n3clR8R+e5rQVDVpG4QR7I+9yAY48= 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=lj4zQ/k/yu01ARgkyBeTOKuSoVDiR5D4J5KvwtDC7qI=; b=sMzso/qVsL4kBFtmEYhVmt/+NNdzOYqY8IEqo86xMCo876JNuCLQ52SrfdpjtSb9s9 lnlnWVOAYj3mPx74lPaWodFmBh7M3Bjgu0DI8G0Axk1ky5is3uAhnfMP4UPDL5YLne2o tPepZI8vFVylCNsuvpz/7ydH3SBQm5MK3cgWep4pPPl1OJ/qs8SOXhUCc90ay3Eh2+Jz bjcKwDIn/dyee18iBpNM/aAzc09UsW3zrS6jF7AX/VRs4szRxj+GJCgLcXPjQscHW958 B71YZxbOWg7rTx4OTyi3b0FmO+zfFYbNXKJ7cs6XyGPCqRym+qpsm6S3BF9h6bOc2Mxn +UQw== X-Gm-Message-State: AElRT7EoprCp0I8sSG8obqB66jllz+3R4aTYWY+Jo4QgT8LbnSejJT70 yamRYZGKmhdGvzSRhz23KPbf9g== X-Google-Smtp-Source: AG47ELuiIr+cAwEvRNGq6dM4tp9gYGstmJNZCs3yxH6XyH/axRko5aK188XBv7I4efppE6+3lryk0w== X-Received: by 2002:a17:902:983:: with SMTP id 3-v6mr9572077pln.278.1521143272889; Thu, 15 Mar 2018 12:47:52 -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 s7sm3857251pgr.90.2018.03.15.12.47.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Mar 2018 12:47:51 -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 v4 1/2] kernel.h: Introduce const_max() for VLA removal Date: Thu, 15 Mar 2018 12:47:45 -0700 Message-Id: <1521143266-31350-2-git-send-email-keescook@chromium.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1521143266-31350-1-git-send-email-keescook@chromium.org> References: <1521143266-31350-1-git-send-email-keescook@chromium.org> MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@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(), 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_not_const_arg’ declared with attribute error: const_max() used with non-compile-time constant arg To gain the ability to compare differing types, the arguments are explicitly cast to size_t. Without this, some compiler versions will fail when comparing different enum types or similar constant expression cases. With the casting, it's possible to do things like: int foo[const_max(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..012f588b5a25 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 - return maximum of two positive compile-time constant values + * @x: first compile-time constant value + * @y: second compile-time constant value + * + * This has no type checking nor multi-evaluation defenses, and must + * only ever be used with positive compile-time constant values (for + * example when calculating a stack array size). + */ +size_t __error_not_const_arg(void) \ +__compiletime_error("const_max() used with non-compile-time constant arg"); +#define const_max(x, y) \ + __builtin_choose_expr(__builtin_constant_p(x) && \ + __builtin_constant_p(y), \ + (size_t)(x) > (size_t)(y) ? \ + (size_t)(x) : \ + (size_t)(y), \ + __error_not_const_arg()) + +/** * min3 - return minimum of three values * @x: first value * @y: second value