aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee802154
diff options
context:
space:
mode:
authorMartin Townsend <mtownsend1973@gmail.com>2014-11-06 14:15:13 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-11-06 16:09:48 -0500
commit56b2c3eea398c772dd895dc62c18cbdd1ba127b1 (patch)
treea4d6ab3f6bbf38f4c5b3cb66cc6f77d142397e32 /net/ieee802154
parent9645c76c7c233da82ff7aced0177c8a131a51e70 (diff)
6lowpan: move skb_free from error paths in decompression
Currently we ensure that the skb is freed on every error path in IPHC decompression which makes it easy to introduce skb leaks. By centralising the skb_free into the receive function it makes future decompression routines easier to maintain. It does come at the expense of ensuring that the skb passed into the decompression routine must not be copied. Signed-off-by: Martin Townsend <mtownsend1973@gmail.com> Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com> Acked-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/ieee802154')
-rw-r--r--net/ieee802154/6lowpan_rtnl.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index a96b64c9a73d..290e14f2e92e 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -176,13 +176,13 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
176 raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len); 176 raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len);
177 /* at least two bytes will be used for the encoding */ 177 /* at least two bytes will be used for the encoding */
178 if (skb->len < 2) 178 if (skb->len < 2)
179 goto drop; 179 return -EINVAL;
180 180
181 if (lowpan_fetch_skb_u8(skb, &iphc0)) 181 if (lowpan_fetch_skb_u8(skb, &iphc0))
182 goto drop; 182 return -EINVAL;
183 183
184 if (lowpan_fetch_skb_u8(skb, &iphc1)) 184 if (lowpan_fetch_skb_u8(skb, &iphc1))
185 goto drop; 185 return -EINVAL;
186 186
187 ieee802154_addr_to_sa(&sa, &hdr->source); 187 ieee802154_addr_to_sa(&sa, &hdr->source);
188 ieee802154_addr_to_sa(&da, &hdr->dest); 188 ieee802154_addr_to_sa(&da, &hdr->dest);
@@ -200,10 +200,6 @@ iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
200 return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type, 200 return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type,
201 IEEE802154_ADDR_LEN, dap, da.addr_type, 201 IEEE802154_ADDR_LEN, dap, da.addr_type,
202 IEEE802154_ADDR_LEN, iphc0, iphc1); 202 IEEE802154_ADDR_LEN, iphc0, iphc1);
203
204drop:
205 kfree_skb(skb);
206 return -EINVAL;
207} 203}
208 204
209static struct sk_buff* 205static struct sk_buff*
@@ -522,7 +518,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
522 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ 518 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
523 ret = iphc_decompress(skb, &hdr); 519 ret = iphc_decompress(skb, &hdr);
524 if (ret < 0) 520 if (ret < 0)
525 goto drop; 521 goto drop_skb;
526 522
527 return lowpan_give_skb_to_devices(skb, NULL); 523 return lowpan_give_skb_to_devices(skb, NULL);
528 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ 524 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
@@ -530,7 +526,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
530 if (ret == 1) { 526 if (ret == 1) {
531 ret = iphc_decompress(skb, &hdr); 527 ret = iphc_decompress(skb, &hdr);
532 if (ret < 0) 528 if (ret < 0)
533 goto drop; 529 goto drop_skb;
534 530
535 return lowpan_give_skb_to_devices(skb, NULL); 531 return lowpan_give_skb_to_devices(skb, NULL);
536 } else if (ret == -1) { 532 } else if (ret == -1) {
@@ -543,7 +539,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
543 if (ret == 1) { 539 if (ret == 1) {
544 ret = iphc_decompress(skb, &hdr); 540 ret = iphc_decompress(skb, &hdr);
545 if (ret < 0) 541 if (ret < 0)
546 goto drop; 542 goto drop_skb;
547 543
548 return lowpan_give_skb_to_devices(skb, NULL); 544 return lowpan_give_skb_to_devices(skb, NULL);
549 } else if (ret == -1) { 545 } else if (ret == -1) {