Re: [PATCH v4 8/9] netlink: fix nla_put_{u8,u16,u32} for KASAN

2017-09-25 Thread David Miller
From: Arnd Bergmann 
Date: Fri, 22 Sep 2017 23:29:19 +0200

> When CONFIG_KASAN is enabled, the "--param asan-stack=1" causes rather large
> stack frames in some functions. This goes unnoticed normally because
> CONFIG_FRAME_WARN is disabled with CONFIG_KASAN by default as of commit
> 3f181b4d8652 ("lib/Kconfig.debug: disable -Wframe-larger-than warnings with
> KASAN=y").
> 
> The kernelci.org build bot however has the warning enabled and that led
> me to investigate it a little further, as every build produces these warnings:
> 
> net/wireless/nl80211.c:4389:1: warning: the frame size of 2240 bytes is 
> larger than 2048 bytes [-Wframe-larger-than=]
> net/wireless/nl80211.c:1895:1: warning: the frame size of 3776 bytes is 
> larger than 2048 bytes [-Wframe-larger-than=]
> net/wireless/nl80211.c:1410:1: warning: the frame size of 2208 bytes is 
> larger than 2048 bytes [-Wframe-larger-than=]
> net/bridge/br_netlink.c:1282:1: warning: the frame size of 2544 bytes is 
> larger than 2048 bytes [-Wframe-larger-than=]
> 
> Most of this problem is now solved in gcc-8, which can consolidate
> the stack slots for the inline function arguments. On older compilers
> we can add a workaround by declaring a local variable in each function
> to pass the inline function argument.
> 
> Cc: sta...@vger.kernel.org
> Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715
> Signed-off-by: Arnd Bergmann 

Applied.


[PATCH v4 8/9] netlink: fix nla_put_{u8,u16,u32} for KASAN

2017-09-22 Thread Arnd Bergmann
When CONFIG_KASAN is enabled, the "--param asan-stack=1" causes rather large
stack frames in some functions. This goes unnoticed normally because
CONFIG_FRAME_WARN is disabled with CONFIG_KASAN by default as of commit
3f181b4d8652 ("lib/Kconfig.debug: disable -Wframe-larger-than warnings with
KASAN=y").

The kernelci.org build bot however has the warning enabled and that led
me to investigate it a little further, as every build produces these warnings:

net/wireless/nl80211.c:4389:1: warning: the frame size of 2240 bytes is larger 
than 2048 bytes [-Wframe-larger-than=]
net/wireless/nl80211.c:1895:1: warning: the frame size of 3776 bytes is larger 
than 2048 bytes [-Wframe-larger-than=]
net/wireless/nl80211.c:1410:1: warning: the frame size of 2208 bytes is larger 
than 2048 bytes [-Wframe-larger-than=]
net/bridge/br_netlink.c:1282:1: warning: the frame size of 2544 bytes is larger 
than 2048 bytes [-Wframe-larger-than=]

Most of this problem is now solved in gcc-8, which can consolidate
the stack slots for the inline function arguments. On older compilers
we can add a workaround by declaring a local variable in each function
to pass the inline function argument.

Cc: sta...@vger.kernel.org
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715
Signed-off-by: Arnd Bergmann 
---
 include/net/netlink.h | 73 ++-
 1 file changed, 55 insertions(+), 18 deletions(-)

diff --git a/include/net/netlink.h b/include/net/netlink.h
index e51cf5f81597..14c289393071 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -773,7 +773,10 @@ static inline int nla_parse_nested(struct nlattr *tb[], 
int maxtype,
  */
 static inline int nla_put_u8(struct sk_buff *skb, int attrtype, u8 value)
 {
-   return nla_put(skb, attrtype, sizeof(u8), );
+   /* temporary variables to work around GCC PR81715 with asan-stack=1 */
+   u8 tmp = value;
+
+   return nla_put(skb, attrtype, sizeof(u8), );
 }
 
 /**
@@ -784,7 +787,9 @@ static inline int nla_put_u8(struct sk_buff *skb, int 
attrtype, u8 value)
  */
 static inline int nla_put_u16(struct sk_buff *skb, int attrtype, u16 value)
 {
-   return nla_put(skb, attrtype, sizeof(u16), );
+   u16 tmp = value;
+
+   return nla_put(skb, attrtype, sizeof(u16), );
 }
 
 /**
@@ -795,7 +800,9 @@ static inline int nla_put_u16(struct sk_buff *skb, int 
attrtype, u16 value)
  */
 static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value)
 {
-   return nla_put(skb, attrtype, sizeof(__be16), );
+   __be16 tmp = value;
+
+   return nla_put(skb, attrtype, sizeof(__be16), );
 }
 
 /**
@@ -806,7 +813,9 @@ static inline int nla_put_be16(struct sk_buff *skb, int 
attrtype, __be16 value)
  */
 static inline int nla_put_net16(struct sk_buff *skb, int attrtype, __be16 
value)
 {
-   return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, value);
+   __be16 tmp = value;
+
+   return nla_put_be16(skb, attrtype | NLA_F_NET_BYTEORDER, tmp);
 }
 
 /**
@@ -817,7 +826,9 @@ static inline int nla_put_net16(struct sk_buff *skb, int 
attrtype, __be16 value)
  */
 static inline int nla_put_le16(struct sk_buff *skb, int attrtype, __le16 value)
 {
-   return nla_put(skb, attrtype, sizeof(__le16), );
+   __le16 tmp = value;
+
+   return nla_put(skb, attrtype, sizeof(__le16), );
 }
 
 /**
@@ -828,7 +839,9 @@ static inline int nla_put_le16(struct sk_buff *skb, int 
attrtype, __le16 value)
  */
 static inline int nla_put_u32(struct sk_buff *skb, int attrtype, u32 value)
 {
-   return nla_put(skb, attrtype, sizeof(u32), );
+   u32 tmp = value;
+
+   return nla_put(skb, attrtype, sizeof(u32), );
 }
 
 /**
@@ -839,7 +852,9 @@ static inline int nla_put_u32(struct sk_buff *skb, int 
attrtype, u32 value)
  */
 static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value)
 {
-   return nla_put(skb, attrtype, sizeof(__be32), );
+   __be32 tmp = value;
+
+   return nla_put(skb, attrtype, sizeof(__be32), );
 }
 
 /**
@@ -850,7 +865,9 @@ static inline int nla_put_be32(struct sk_buff *skb, int 
attrtype, __be32 value)
  */
 static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 
value)
 {
-   return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, value);
+   __be32 tmp = value;
+
+   return nla_put_be32(skb, attrtype | NLA_F_NET_BYTEORDER, tmp);
 }
 
 /**
@@ -861,7 +878,9 @@ static inline int nla_put_net32(struct sk_buff *skb, int 
attrtype, __be32 value)
  */
 static inline int nla_put_le32(struct sk_buff *skb, int attrtype, __le32 value)
 {
-   return nla_put(skb, attrtype, sizeof(__le32), );
+   __le32 tmp = value;
+
+   return nla_put(skb, attrtype, sizeof(__le32), );
 }
 
 /**
@@ -874,7 +893,9 @@ static inline int nla_put_le32(struct sk_buff *skb, int 
attrtype, __le32 value)
 static inline int nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
u64 value,