]>
Commit | Line | Data |
---|---|---|
c1f358be FG |
1 | From 7dd7eb9513bd02184d45f000ab69d78cb1fa1531 Mon Sep 17 00:00:00 2001 |
2 | From: "David S. Miller" <davem@davemloft.net> | |
3 | Date: Wed, 17 May 2017 22:54:11 -0400 | |
4 | Subject: [PATCH] ipv6: Check ip6_find_1stfragopt() return value properly. | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | Do not use unsigned variables to see if it returns a negative | |
10 | error or not. | |
11 | ||
12 | Fixes: 2423496af35d ("ipv6: Prevent overrun when parsing v6 header options") | |
13 | Reported-by: Julia Lawall <julia.lawall@lip6.fr> | |
14 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
15 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
16 | --- | |
17 | net/ipv6/ip6_offload.c | 9 ++++----- | |
18 | net/ipv6/ip6_output.c | 7 +++---- | |
19 | net/ipv6/udp_offload.c | 8 +++++--- | |
20 | 3 files changed, 12 insertions(+), 12 deletions(-) | |
21 | ||
22 | diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c | |
23 | index eab36abc9f22..280268f1dd7b 100644 | |
24 | --- a/net/ipv6/ip6_offload.c | |
25 | +++ b/net/ipv6/ip6_offload.c | |
26 | @@ -63,7 +63,6 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |
27 | const struct net_offload *ops; | |
28 | int proto; | |
29 | struct frag_hdr *fptr; | |
30 | - unsigned int unfrag_ip6hlen; | |
31 | unsigned int payload_len; | |
32 | u8 *prevhdr; | |
33 | int offset = 0; | |
34 | @@ -116,10 +115,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |
35 | skb->network_header = (u8 *)ipv6h - skb->head; | |
36 | ||
37 | if (udpfrag) { | |
38 | - unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); | |
39 | - if (unfrag_ip6hlen < 0) | |
40 | - return ERR_PTR(unfrag_ip6hlen); | |
41 | - fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen); | |
42 | + int err = ip6_find_1stfragopt(skb, &prevhdr); | |
43 | + if (err < 0) | |
44 | + return ERR_PTR(err); | |
45 | + fptr = (struct frag_hdr *)((u8 *)ipv6h + err); | |
46 | fptr->frag_off = htons(offset); | |
47 | if (skb->next) | |
48 | fptr->frag_off |= htons(IP6_MF); | |
49 | diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c | |
50 | index 01deecda2f84..d4a31becbd25 100644 | |
51 | --- a/net/ipv6/ip6_output.c | |
52 | +++ b/net/ipv6/ip6_output.c | |
53 | @@ -597,11 +597,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, | |
54 | int ptr, offset = 0, err = 0; | |
55 | u8 *prevhdr, nexthdr = 0; | |
56 | ||
57 | - hlen = ip6_find_1stfragopt(skb, &prevhdr); | |
58 | - if (hlen < 0) { | |
59 | - err = hlen; | |
60 | + err = ip6_find_1stfragopt(skb, &prevhdr); | |
61 | + if (err < 0) | |
62 | goto fail; | |
63 | - } | |
64 | + hlen = err; | |
65 | nexthdr = *prevhdr; | |
66 | ||
67 | mtu = ip6_skb_dst_mtu(skb); | |
68 | diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c | |
69 | index b348cff47395..a2267f80febb 100644 | |
70 | --- a/net/ipv6/udp_offload.c | |
71 | +++ b/net/ipv6/udp_offload.c | |
72 | @@ -29,6 +29,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |
73 | u8 frag_hdr_sz = sizeof(struct frag_hdr); | |
74 | __wsum csum; | |
75 | int tnl_hlen; | |
76 | + int err; | |
77 | ||
78 | mss = skb_shinfo(skb)->gso_size; | |
79 | if (unlikely(skb->len <= mss)) | |
80 | @@ -90,9 +91,10 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |
81 | /* Find the unfragmentable header and shift it left by frag_hdr_sz | |
82 | * bytes to insert fragment header. | |
83 | */ | |
84 | - unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); | |
85 | - if (unfrag_ip6hlen < 0) | |
86 | - return ERR_PTR(unfrag_ip6hlen); | |
87 | + err = ip6_find_1stfragopt(skb, &prevhdr); | |
88 | + if (err < 0) | |
89 | + return ERR_PTR(err); | |
90 | + unfrag_ip6hlen = err; | |
91 | nexthdr = *prevhdr; | |
92 | *prevhdr = NEXTHDR_FRAGMENT; | |
93 | unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + | |
94 | -- | |
95 | 2.11.0 | |
96 |