From patchwork Thu Dec 14 23:32:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Morton X-Patchwork-Id: 122029 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp7463199qgn; Thu, 14 Dec 2017 15:32:42 -0800 (PST) X-Google-Smtp-Source: ACJfBosDSo5zf+PWkK5vsI91ggVLZzGDnjOGhS7KEViuHe9PFWK6xeWS/Io3MRDTCpxrSw/FWQ37 X-Received: by 10.84.247.148 with SMTP id o20mr11263686pll.137.1513294362000; Thu, 14 Dec 2017 15:32:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513294361; cv=none; d=google.com; s=arc-20160816; b=DFfAfR2OaeYN4d6pZSZNFfiubPesRLWcaTht4bZkG59QS6O9dBSsfG2YKQ/4rHdgOA SxioQ/rEvbjFQFvIrzJxqOqgYjq0ZSp1BPB5LIGebQ+VZ9ezqakAjQSlg1M0PslNefAi tCmIoR2UeEoY7tDymJNS5mnijmg18a+pGw4cIWeTK3ehoiA3XYLckt1Vwg5QjJ3Ta9si V2bqiiezmKVbQ/oGVzsXiRwLyYfh9E/sVTeLliIB4ekuyvJDGjHcuCfQaecehDmCn5mi yBKJjk5NG4TQOevS5uiNeHZw2g/+ZunBDFr3w1sAmRc6IRKjRX3bvlTad+20DwnlCPep EPDw== 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 :user-agent:message-id:subject:to:from:date :arc-authentication-results; bh=Q6mineG7Fjz/5G2FNL9VwgMFm11uzgLdQI7YYauMhAU=; b=sPqMVKC6x2qC2KcTJIi1HWf5b8WPL2xxdTjPaKCVkMWqP4C+MbRNUkZj8rSCyO3c6/ xcRmzLO2IwjcFmxZhgB0RkEwqrIVn+UAdZea+np19s/gAuOuzm/wgF8UMoivNtMBXfAh VqE4CcwtIKQjKCtz+6i6R6lMzwWWdj97FD0WTWUOBC49LOtqlN8HhWjelKajYlGgUo1P OudSn6dZl5k6NiUusUnFFnbaejOPLxoK0opsDlq0JZ1q4L4R07Ag9Y+BacF1dQ1ad1Hu L+Kdevuv35lM0B2Qv8rPgJ8AnXJnNesJj77VtfOEPgaz8xcY1JcVxutJOdp+9M8xkH4/ XDuw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-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 v40si3490786plg.599.2017.12.14.15.32.41; Thu, 14 Dec 2017 15:32:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of stable-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 stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754461AbdLNXcj (ORCPT + 10 others); Thu, 14 Dec 2017 18:32:39 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:54280 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754292AbdLNXcg (ORCPT ); Thu, 14 Dec 2017 18:32:36 -0500 Received: from akpm3.svl.corp.google.com (unknown [104.133.9.92]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id C4E02BE6; Thu, 14 Dec 2017 23:32:35 +0000 (UTC) Date: Thu, 14 Dec 2017 15:32:34 -0800 From: akpm@linux-foundation.org To: torvalds@linux-foundation.org, mm-commits@vger.kernel.org, akpm@linux-foundation.org, arnd@arndb.de, aryabinin@virtuozzo.com, danielmicay@gmail.com, dan.j.williams@intel.com, dvyukov@google.com, glider@google.com, gregkh@linuxfoundation.org, keescook@chromium.org, mchehab@kernel.org, mwilck@suse.com, stable@vger.kernel.org Subject: [patch 04/17] string.h: workaround for increased stack usage Message-ID: <5a330a12.9Cb9UAUNuWpJv46D%akpm@linux-foundation.org> User-Agent: Heirloom mailx 12.5 6/20/10 MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Arnd Bergmann Subject: string.h: workaround for increased stack usage The hardened strlen() function causes rather large stack usage in at least one file in the kernel, in particular when CONFIG_KASAN is enabled: drivers/media/usb/em28xx/em28xx-dvb.c: In function 'em28xx_dvb_init': drivers/media/usb/em28xx/em28xx-dvb.c:2062:1: error: the frame size of 3256 bytes is larger than 204 bytes [-Werror=frame-larger-than=] Analyzing this problem led to the discovery that gcc fails to merge the stack slots for the i2c_board_info[] structures after we strlcpy() into them, due to the 'noreturn' attribute on the source string length check. I reported this as a gcc bug, but it is unlikely to get fixed for gcc-8, since it is relatively easy to work around, and it gets triggered rarely. An earlier workaround I did added an empty inline assembly statement before the call to fortify_panic(), which works surprisingly well, but is really ugly and unintuitive. This is a new approach to the same problem, this time addressing it by not calling the 'extern __real_strnlen()' function for string constants where __builtin_strlen() is a compile-time constant and therefore known to be safe. We do this by checking if the last character in the string is a compile-time constant '\0'. If it is, we can assume that strlen() of the string is also constant. As a side-effect, this should also improve the object code output for any other call of strlen() on a string constant. [akpm@linux-foundation.org: add comment] Link: http://lkml.kernel.org/r/20171205215143.3085755-1-arnd@arndb.de Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82365 Link: https://patchwork.kernel.org/patch/9980413/ Link: https://patchwork.kernel.org/patch/9974047/ Fixes: 6974f0c4555 ("include/linux/string.h: add the option of fortified string.h functions") Signed-off-by: Arnd Bergmann Cc: Kees Cook Cc: Mauro Carvalho Chehab Cc: Dmitry Vyukov Cc: Alexander Potapenko Cc: Andrey Ryabinin Cc: Daniel Micay Cc: Greg Kroah-Hartman Cc: Martin Wilck Cc: Dan Williams Cc: Signed-off-by: Andrew Morton --- include/linux/string.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff -puN include/linux/string.h~stringh-work-around-for-increased-stack-usage include/linux/string.h --- a/include/linux/string.h~stringh-work-around-for-increased-stack-usage +++ a/include/linux/string.h @@ -259,7 +259,10 @@ __FORTIFY_INLINE __kernel_size_t strlen( { __kernel_size_t ret; size_t p_size = __builtin_object_size(p, 0); - if (p_size == (size_t)-1) + + /* Work around gcc excess stack consumption issue */ + if (p_size == (size_t)-1 || + (__builtin_constant_p(p[p_size - 1]) && p[p_size - 1] == '\0')) return __builtin_strlen(p); ret = strnlen(p, p_size); if (p_size <= ret)