From patchwork Thu Jun 22 17:13:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 9804971 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 54CEA60329 for ; Thu, 22 Jun 2017 17:17:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9AB1F2621D for ; Thu, 22 Jun 2017 17:17:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8ABB0285A8; Thu, 22 Jun 2017 17:17:01 +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.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI 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 E00C82621D for ; Thu, 22 Jun 2017 17:17:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753759AbdFVRPh (ORCPT ); Thu, 22 Jun 2017 13:15:37 -0400 Received: from mout.kundenserver.de ([212.227.17.10]:51731 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753601AbdFVRPe (ORCPT ); Thu, 22 Jun 2017 13:15:34 -0400 Received: from wuerfel.lan ([5.56.224.194]) by mrelayeu.kundenserver.de (mreue103 [212.227.15.145]) with ESMTPA (Nemesis) id 0Lf0KF-1e8MrH0XLb-00qjBM; Thu, 22 Jun 2017 19:14:08 +0200 From: Arnd Bergmann To: Andrew Morton Cc: kasan-dev@googlegroups.com, Dmitry Vyukov , Alexander Potapenko , Andrey Ryabinin , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Arend van Spriel , Arnd Bergmann , Masahiro Yamada , Michal Marek , Kees Cook , Ingo Molnar , "David S . Miller" , linux-kbuild@vger.kernel.org, Samuel Thibault , Greg Kroah-Hartman , Jiri Slaby , stable@vger.kernel.org Subject: [PATCH v3 07/11] tty: improve tty_insert_flip_char() fast path Date: Thu, 22 Jun 2017 19:13:51 +0200 Message-Id: <20170622171355.267192-8-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170622171355.267192-1-arnd@arndb.de> References: <20170622171355.267192-1-arnd@arndb.de> X-Provags-ID: V03:K0:LJnE2AH47CPNvTjAerHeC+M8iITtIqJFb1OqY6OgIGS3ZKGI5pD gs7+Zg4UbFSoN0eaxGvhULuiiaciOEGriyc/n7vlDB8ieukkPLoVd8cdEAEtEsrvHdfLVbX Rs8Zv3nqacgkdUvJCBX8n/u8XvjtMcgl71hBU5HDmAeRLBeUAiMyDrbIlfXUlvkkGetY1mH ZskgeRNL/8yIiK+CRH+/w== X-UI-Out-Filterresults: notjunk:1; V01:K0:9jx529M6hBw=:MucfFN7UuGtRNQD/3ybJqs CXkmG0RUDFSwUVJ36knfzPOcaGaoXlwpG6e+ya4se8q2Honhu0elJii4SjVVcrl9zmFSj0Brc hw8Ho+SdDSQ6md5BrVU0O8DtNHeUp81cmmNuhHVFy9LjZRR3hQoP+zo+u7Ps/tI4MFBjOjG0f ebfKgfYVbTkn0D0gTW4N983RH/cdWvIs0t3EIfjmDlN11OPZS92bzOB/AugBqVSBem/PKuq9i 0sJrSkJs+6kDto/F5ojsoo6fhfx4Ta+eqrGmBQJGaS3paDt+BgkzUrB1Gb7wgCFklQN9vjsCG RLwMn72rNGgZP/ssRlCffPqIsqMjy0WgL6FE/glnqKbrweiqiI4v/bG8SsEZKro44wbdHCQZz U7Jn4g6jXEbDD0AU+MPSUrpzmQzLiWnhi/rsmgUN3p+Jc8YQQ6Om9uFbo+FYFrcsIu93cfQ4j d6VFXu9Brz6HUjBhSL6f9xswcN0MW2Vr5TiHRxtq7yg7Q9tTfHppyHwMcB1shcGsADJsXYWaz 8u61e5p7RxpJ29RdEYXJlbMH3wF1rohHr47pWmrQxYfVf+8sftfYR268Hu07XGA8Nsv2/j8ZY o7Aaf8SwQHZjjFG6MjG38lS2BFWbS0b1KdByLFenLBPvzeTyCBkzG7yoMJv/BM76AI64/Xe5t gpcAz7+WjIQghGggSHIvogSZk3ED54uYIZlFjheirivrPmKWXwydQnYz02Rn6QqN6ifo= Sender: linux-kbuild-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP kernelci.org reports a crazy stack usage for the VT code when CONFIG_KASAN is enabled: drivers/tty/vt/keyboard.c: In function 'kbd_keycode': drivers/tty/vt/keyboard.c:1452:1: error: the frame size of 2240 bytes is larger than 2048 bytes [-Werror=frame-larger-than=] The problem is that tty_insert_flip_char() gets inlined many times into kbd_keycode(), and also into other functions, and each copy requires 128 bytes for stack redzone to check for a possible out-of-bounds access on the 'ch' and 'flags' arguments that are passed into tty_insert_flip_string_flags as a variable-length string. This introduces a new __tty_insert_flip_char() function for the slow path, which receives the two arguments by value. This completely avoids the problem and the stack usage goes back down to around 100 bytes. Without KASAN, this is also slightly better, as we don't have to spill the arguments to the stack but can simply pass 'ch' and 'flag' in registers, saving a few bytes in .text for each call site. This should be backported to linux-4.0 or later, which first introduced the stack sanitizer in the kernel. Cc: stable@vger.kernel.org Fixes: c420f167db8c ("kasan: enable stack instrumentation") Signed-off-by: Arnd Bergmann --- I already submitted this separately to Greg, but he hasn't replied yet. I assume that it's fine if Andrew picks it up along with the other patches and drops it again in case Greg applies it to linux-next. drivers/tty/tty_buffer.c | 24 ++++++++++++++++++++++++ include/linux/tty_flip.h | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 4e7a4e9dcf4d..2da05fa37aec 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -362,6 +362,30 @@ int tty_insert_flip_string_flags(struct tty_port *port, EXPORT_SYMBOL(tty_insert_flip_string_flags); /** + * __tty_insert_flip_char - Add one character to the tty buffer + * @port: tty port + * @ch: character + * @flag: flag byte + * + * Queue a single byte to the tty buffering, with an optional flag. + * This is the slow path of tty_insert_flip_char. + */ +int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) +{ + struct tty_buffer *tb = port->buf.tail; + int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; + + if (!tty_buffer_request_room(port, 1)) + return 0; + + *flag_buf_ptr(tb, tb->used) = flag; + *char_buf_ptr(tb, tb->used++) = ch; + + return 1; +} +EXPORT_SYMBOL(__tty_insert_flip_char); + +/** * tty_schedule_flip - push characters to ldisc * @port: tty port to push from * diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index c28dd523f96e..d43837f2ce3a 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -12,6 +12,7 @@ extern int tty_prepare_flip_string(struct tty_port *port, unsigned char **chars, size_t size); extern void tty_flip_buffer_push(struct tty_port *port); void tty_schedule_flip(struct tty_port *port); +int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag); static inline int tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) @@ -26,7 +27,7 @@ static inline int tty_insert_flip_char(struct tty_port *port, *char_buf_ptr(tb, tb->used++) = ch; return 1; } - return tty_insert_flip_string_flags(port, &ch, &flag, 1); + return __tty_insert_flip_char(port, ch, flag); } static inline int tty_insert_flip_string(struct tty_port *port,