aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-05-17 22:54:11 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-17 22:54:11 -0400
commit7dd7eb9513bd02184d45f000ab69d78cb1fa1531 (patch)
tree069fed66bdc18c6043c981748bb28057fbc1bcf2 /net
parent579f1d926c66cc0bd3bd87b1fe2e091084b07430 (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.c9
-rw-r--r--net/ipv6/ip6_output.c7
-rw-r--r--net/ipv6/udp_offload.c8
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)) +