LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

[PATCH 1/4] [v2] structleak: disable STRUCTLEAK_BYREF in combination wit

To: Kees Cook <keescook@xxxxxxxxxxxx>, James Morris <jmorris@xxxxxxxxx>, "Serge E. Hallyn" <serge@xxxxxxxxxx>
Subject: [PATCH 1/4] [v2] structleak: disable STRUCTLEAK_BYREF in combination with KASAN_STACK
Cc: James Smart <james.smart@xxxxxxxxxxxx>, Dick Kennedy <dick.kennedy@xxxxxxxxxxxx>, "James E . J . Bottomley" <jejb@xxxxxxxxxxxxx>, "Martin K . Petersen" <martin.petersen@xxxxxxxxxx>, Larry Finger <Larry.Finger@xxxxxxxxxxxx>, Florian Schilhabel <florian.c.schilhabel@xxxxxxxxxxxxxx>, Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>, "David S . Miller" <davem@xxxxxxxxxxxxx>, Wensong Zhang <wensong@xxxxxxxxxxxx>, Simon Horman <horms@xxxxxxxxxxxx>, Julian Anastasov <ja@xxxxxx>, Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>, linux-scsi@xxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, devel@xxxxxxxxxxxxxxxxxxxx, netdev@xxxxxxxxxxxxxxx, lvs-devel@xxxxxxxxxxxxxxx, netfilter-devel@xxxxxxxxxxxxxxx, coreteam@xxxxxxxxxxxxx, Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>, Arnd Bergmann <arnd@xxxxxxxx>, Masahiro Yamada <yamada.masahiro@xxxxxxxxxxxxx>, Alexander Potapenko <glider@xxxxxxxxxx>, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>, Michal Hocko <mhocko@xxxxxxx>, Thomas Gleixner <tglx@xxxxxxxxxxxxx>, linux-security-module@xxxxxxxxxxxxxxx
From: Arnd Bergmann <arnd@xxxxxxxx>
Date: Fri, 28 Jun 2019 14:37:46 +0200
The combination of KASAN_STACK and GCC_PLUGIN_STRUCTLEAK_BYREF
leads to much larger kernel stack usage, as seen from the warnings
about functions that now exceed the 2048 byte limit:

drivers/media/i2c/tvp5150.c:253:1: error: the frame size of 3936 bytes is 
larger than 2048 bytes
drivers/media/tuners/r820t.c:1327:1: error: the frame size of 2816 bytes is 
larger than 2048 bytes
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c:16552:1: error: 
the frame size of 3144 bytes is larger than 2048 bytes 
[-Werror=frame-larger-than=]
fs/ocfs2/aops.c:1892:1: error: the frame size of 2088 bytes is larger than 2048 
bytes
fs/ocfs2/dlm/dlmrecovery.c:737:1: error: the frame size of 2088 bytes is larger 
than 2048 bytes
fs/ocfs2/namei.c:1677:1: error: the frame size of 2584 bytes is larger than 
2048 bytes
fs/ocfs2/super.c:1186:1: error: the frame size of 2640 bytes is larger than 
2048 bytes
fs/ocfs2/xattr.c:3678:1: error: the frame size of 2176 bytes is larger than 
2048 bytes
net/bluetooth/l2cap_core.c:7056:1: error: the frame size of 2144 bytes is 
larger than 2048 bytes [-Werror=frame-larger-than=]
net/bluetooth/l2cap_core.c: In function 'l2cap_recv_frame':
net/bridge/br_netlink.c:1505:1: error: the frame size of 2448 bytes is larger 
than 2048 bytes
net/ieee802154/nl802154.c:548:1: error: the frame size of 2232 bytes is larger 
than 2048 bytes
net/wireless/nl80211.c:1726:1: error: the frame size of 2224 bytes is larger 
than 2048 bytes
net/wireless/nl80211.c:2357:1: error: the frame size of 4584 bytes is larger 
than 2048 bytes
net/wireless/nl80211.c:5108:1: error: the frame size of 2760 bytes is larger 
than 2048 bytes
net/wireless/nl80211.c:6472:1: error: the frame size of 2112 bytes is larger 
than 2048 bytes

The structleak plugin was previously disabled for CONFIG_COMPILE_TEST,
but meant we missed some bugs, so this time we should address them.

The frame size warnings are distracting, and risking a kernel stack
overflow is generally not beneficial to performance, so it may be best
to disallow that particular combination. This can be done by turning
off either one. I picked the dependency in GCC_PLUGIN_STRUCTLEAK_BYREF
and GCC_PLUGIN_STRUCTLEAK_BYREF_ALL, as this option is designed to
make uninitialized stack usage less harmful when enabled on its own,
but it also prevents KASAN from detecting those cases in which it was
in fact needed.

KASAN_STACK is currently implied by KASAN on gcc, but could be made a
user selectable option if we want to allow combining (non-stack) KASAN
with GCC_PLUGIN_STRUCTLEAK_BYREF.

Note that it would be possible to specifically address the files that
print the warning, but presumably the overall stack usage is still
significantly higher than in other configurations, so this would not
address the full problem.

I could not test this with CONFIG_INIT_STACK_ALL, which may or may not
suffer from a similar problem.

Fixes: 81a56f6dcd20 ("gcc-plugins: structleak: Generalize to all variable 
types")
Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
---
[v2] do it for both GCC_PLUGIN_STRUCTLEAK_BYREF and 
GCC_PLUGIN_STRUCTLEAK_BYREF_ALL.
---
 security/Kconfig.hardening | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
index a1ffe2eb4d5f..af4c979b38ee 100644
--- a/security/Kconfig.hardening
+++ b/security/Kconfig.hardening
@@ -61,6 +61,7 @@ choice
        config GCC_PLUGIN_STRUCTLEAK_BYREF
                bool "zero-init structs passed by reference (strong)"
                depends on GCC_PLUGINS
+               depends on !(KASAN && KASAN_STACK=1)
                select GCC_PLUGIN_STRUCTLEAK
                help
                  Zero-initialize any structures on the stack that may
@@ -70,9 +71,15 @@ choice
                  exposures, like CVE-2017-1000410:
                  https://git.kernel.org/linus/06e7e776ca4d3654
 
+                 As a side-effect, this keeps a lot of variables on the
+                 stack that can otherwise be optimized out, so combining
+                 this with CONFIG_KASAN_STACK can lead to a stack overflow
+                 and is disallowed.
+
        config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
                bool "zero-init anything passed by reference (very strong)"
                depends on GCC_PLUGINS
+               depends on !(KASAN && KASAN_STACK=1)
                select GCC_PLUGIN_STRUCTLEAK
                help
                  Zero-initialize any stack variables that may be passed
-- 
2.20.0


<Prev in Thread] Current Thread [Next in Thread>