diff options
author | David S. Miller <davem@davemloft.net> | 2015-10-23 05:49:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-23 05:49:41 -0400 |
commit | ec3661b42257d9a06cf0d318175623ac7a660113 (patch) | |
tree | 00351145ca8f839024370cf1909358845357bf3a | |
parent | c80dbe04612986fd6104b4a1be21681b113b5ac9 (diff) | |
parent | b72a2b01b686f242028038f630555513c9e4de38 (diff) |
Merge branch 'ipv6-overflow-arith'
Hannes Frederic Sowa says:
====================
overflow-arith: begin to add support for overflow builtins functions
I add a new header, linux/overflow-arith.h, as the central place to add
overflow and wrap-around checking functions. The reason I am doing so
is that it can make use of compiler supported builtin functions which
can leverage hardware.
As I need this for a fix in the ipv6 stack, which is also included in
this series, I propose to add it sooner than later over Davem's net
tree. This is also the reason why I start slowly with only the one
function I need at this time.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/compiler-gcc.h | 4 | ||||
-rw-r--r-- | include/linux/overflow-arith.h | 18 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 6 |
3 files changed, 27 insertions, 1 deletions
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index dfaa7b3e9ae9..82c159e0532a 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
@@ -237,6 +237,10 @@ | |||
237 | #define KASAN_ABI_VERSION 3 | 237 | #define KASAN_ABI_VERSION 3 |
238 | #endif | 238 | #endif |
239 | 239 | ||
240 | #if GCC_VERSION >= 50000 | ||
241 | #define CC_HAVE_BUILTIN_OVERFLOW | ||
242 | #endif | ||
243 | |||
240 | #endif /* gcc version >= 40000 specific checks */ | 244 | #endif /* gcc version >= 40000 specific checks */ |
241 | 245 | ||
242 | #if !defined(__noclone) | 246 | #if !defined(__noclone) |
diff --git a/include/linux/overflow-arith.h b/include/linux/overflow-arith.h new file mode 100644 index 000000000000..e12ccf854a70 --- /dev/null +++ b/include/linux/overflow-arith.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <linux/kernel.h> | ||
4 | |||
5 | #ifdef CC_HAVE_BUILTIN_OVERFLOW | ||
6 | |||
7 | #define overflow_usub __builtin_usub_overflow | ||
8 | |||
9 | #else | ||
10 | |||
11 | static inline bool overflow_usub(unsigned int a, unsigned int b, | ||
12 | unsigned int *res) | ||
13 | { | ||
14 | *res = a - b; | ||
15 | return *res > a ? true : false; | ||
16 | } | ||
17 | |||
18 | #endif | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d03d6da772f3..8dddb45c433e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/overflow-arith.h> | ||
31 | #include <linux/string.h> | 32 | #include <linux/string.h> |
32 | #include <linux/socket.h> | 33 | #include <linux/socket.h> |
33 | #include <linux/net.h> | 34 | #include <linux/net.h> |
@@ -584,7 +585,10 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb, | |||
584 | if (np->frag_size) | 585 | if (np->frag_size) |
585 | mtu = np->frag_size; | 586 | mtu = np->frag_size; |
586 | } | 587 | } |
587 | mtu -= hlen + sizeof(struct frag_hdr); | 588 | |
589 | if (overflow_usub(mtu, hlen + sizeof(struct frag_hdr), &mtu) || | ||
590 | mtu <= 7) | ||
591 | goto fail_toobig; | ||
588 | 592 | ||
589 | frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr, | 593 | frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr, |
590 | &ipv6_hdr(skb)->saddr); | 594 | &ipv6_hdr(skb)->saddr); |