diff options
author | David S. Miller <davem@davemloft.net> | 2017-05-17 22:54:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-17 22:54:11 -0400 |
commit | 7dd7eb9513bd02184d45f000ab69d78cb1fa1531 (patch) | |
tree | 069fed66bdc18c6043c981748bb28057fbc1bcf2 /net | |
parent | 579f1d926c66cc0bd3bd87b1fe2e091084b07430 (diff) |
ipv6: Check ip6_find_1stfragopt() return value properly.
Do not use unsigned variables to see if it returns a negative
error or not.
Fixes: 2423496af35d ("ipv6: Prevent overrun when parsing v6 header options")
Reported-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/ip6_offload.c | 9 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 7 | ||||
-rw-r--r-- | net/ipv6/udp_offload.c | 8 |
3 files changed, 12 insertions, 12 deletions
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index eab36abc9f22..280268f1dd7b 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
@@ -63,7 +63,6 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
63 | const struct net_offload *ops; | 63 | const struct net_offload *ops; |
64 | int proto; | 64 | int proto; |
65 | struct frag_hdr *fptr; | 65 | struct frag_hdr *fptr; |
66 | unsigned int unfrag_ip6hlen; | ||
67 | unsigned int payload_len; | 66 | unsigned int payload_len; |
68 | u8 *prevhdr; | 67 | u8 *prevhdr; |
69 | int offset = 0; | 68 | int offset = 0; |
@@ -116,10 +115,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
116 | skb->network_header = (u8 *)ipv6h - skb->head; | 115 | skb->network_header = (u8 *)ipv6h - skb->head; |
117 | 116 | ||
118 | if (udpfrag) { | 117 | if (udpfrag) { |
119 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); | 118 | int err = ip6_find_1stfragopt(skb, &prevhdr); |
120 | if (unfrag_ip6hlen < 0) | 119 | if (err < 0) |
121 | return ERR_PTR(unfrag_ip6hlen); | 120 | return ERR_PTR(err); |
122 | fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen); | 121 | fptr = (struct frag_hdr *)((u8 *)ipv6h + err); |
123 | fptr->frag_off = htons(offset); | 122 | fptr->frag_off = htons(offset); |
124 | if (skb->next) | 123 | if (skb->next) |
125 | fptr->frag_off |= htons(IP6_MF); | 124 | fptr->frag_off |= htons(IP6_MF); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 01deecda2f84..d4a31becbd25 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -597,11 +597,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, | |||
597 | int ptr, offset = 0, err = 0; | 597 | int ptr, offset = 0, err = 0; |
598 | u8 *prevhdr, nexthdr = 0; | 598 | u8 *prevhdr, nexthdr = 0; |
599 | 599 | ||
600 | hlen = ip6_find_1stfragopt(skb, &prevhdr); | 600 | err = ip6_find_1stfragopt(skb, &prevhdr); |
601 | if (hlen < 0) { | 601 | if (err < 0) |
602 | err = hlen; | ||
603 | goto fail; | 602 | goto fail; |
604 | } | 603 | hlen = err; |
605 | nexthdr = *prevhdr; | 604 | nexthdr = *prevhdr; |
606 | 605 | ||
607 | mtu = ip6_skb_dst_mtu(skb); | 606 | mtu = ip6_skb_dst_mtu(skb); |
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index b348cff47395..a2267f80febb 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
@@ -29,6 +29,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
29 | u8 frag_hdr_sz = sizeof(struct frag_hdr); | 29 | u8 frag_hdr_sz = sizeof(struct frag_hdr); |
30 | __wsum csum; | 30 | __wsum csum; |
31 | int tnl_hlen; | 31 | int tnl_hlen; |
32 | int err; | ||
32 | 33 | ||
33 | mss = skb_shinfo(skb)->gso_size; | 34 | mss = skb_shinfo(skb)->gso_size; |
34 | if (unlikely(skb->len <= mss)) | 35 | if (unlikely(skb->len <= mss)) |
@@ -90,9 +91,10 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
90 | /* Find the unfragmentable header and shift it left by frag_hdr_sz | 91 | /* Find the unfragmentable header and shift it left by frag_hdr_sz |
91 | * bytes to insert fragment header. | 92 | * bytes to insert fragment header. |
92 | */ | 93 | */ |
93 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); | 94 | err = ip6_find_1stfragopt(skb, &prevhdr); |
94 | if (unfrag_ip6hlen < 0) | 95 | if (err < 0) |
95 | return ERR_PTR(unfrag_ip6hlen); | 96 | return ERR_PTR(err); |
97 | unfrag_ip6hlen = err; | ||
96 | nexthdr = *prevhdr; | 98 | nexthdr = *prevhdr; |
97 | *prevhdr = NEXTHDR_FRAGMENT; | 99 | *prevhdr = NEXTHDR_FRAGMENT; |
98 | unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + | 100 | unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + |