diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/6lowpan/iphc.c | 31 | ||||
-rw-r--r-- | net/bluetooth/6lowpan.c | 15 | ||||
-rw-r--r-- | net/ieee802154/6lowpan_rtnl.c | 16 |
3 files changed, 25 insertions, 37 deletions
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index cd5f8b8e34cd..aced97db62f0 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c | |||
@@ -319,7 +319,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
319 | if (iphc1 & LOWPAN_IPHC_CID) { | 319 | if (iphc1 & LOWPAN_IPHC_CID) { |
320 | pr_debug("CID flag is set, increase header with one\n"); | 320 | pr_debug("CID flag is set, increase header with one\n"); |
321 | if (lowpan_fetch_skb(skb, &num_context, sizeof(num_context))) | 321 | if (lowpan_fetch_skb(skb, &num_context, sizeof(num_context))) |
322 | goto drop; | 322 | return -EINVAL; |
323 | } | 323 | } |
324 | 324 | ||
325 | hdr.version = 6; | 325 | hdr.version = 6; |
@@ -331,7 +331,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
331 | */ | 331 | */ |
332 | case 0: /* 00b */ | 332 | case 0: /* 00b */ |
333 | if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) | 333 | if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) |
334 | goto drop; | 334 | return -EINVAL; |
335 | 335 | ||
336 | memcpy(&hdr.flow_lbl, &skb->data[0], 3); | 336 | memcpy(&hdr.flow_lbl, &skb->data[0], 3); |
337 | skb_pull(skb, 3); | 337 | skb_pull(skb, 3); |
@@ -344,7 +344,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
344 | */ | 344 | */ |
345 | case 2: /* 10b */ | 345 | case 2: /* 10b */ |
346 | if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) | 346 | if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) |
347 | goto drop; | 347 | return -EINVAL; |
348 | 348 | ||
349 | hdr.priority = ((tmp >> 2) & 0x0f); | 349 | hdr.priority = ((tmp >> 2) & 0x0f); |
350 | hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); | 350 | hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30); |
@@ -354,7 +354,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
354 | */ | 354 | */ |
355 | case 1: /* 01b */ | 355 | case 1: /* 01b */ |
356 | if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) | 356 | if (lowpan_fetch_skb(skb, &tmp, sizeof(tmp))) |
357 | goto drop; | 357 | return -EINVAL; |
358 | 358 | ||
359 | hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); | 359 | hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30); |
360 | memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); | 360 | memcpy(&hdr.flow_lbl[1], &skb->data[0], 2); |
@@ -371,7 +371,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
371 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { | 371 | if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) { |
372 | /* Next header is carried inline */ | 372 | /* Next header is carried inline */ |
373 | if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr))) | 373 | if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr))) |
374 | goto drop; | 374 | return -EINVAL; |
375 | 375 | ||
376 | pr_debug("NH flag is set, next header carried inline: %02x\n", | 376 | pr_debug("NH flag is set, next header carried inline: %02x\n", |
377 | hdr.nexthdr); | 377 | hdr.nexthdr); |
@@ -383,7 +383,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
383 | } else { | 383 | } else { |
384 | if (lowpan_fetch_skb(skb, &hdr.hop_limit, | 384 | if (lowpan_fetch_skb(skb, &hdr.hop_limit, |
385 | sizeof(hdr.hop_limit))) | 385 | sizeof(hdr.hop_limit))) |
386 | goto drop; | 386 | return -EINVAL; |
387 | } | 387 | } |
388 | 388 | ||
389 | /* Extract SAM to the tmp variable */ | 389 | /* Extract SAM to the tmp variable */ |
@@ -402,7 +402,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
402 | 402 | ||
403 | /* Check on error of previous branch */ | 403 | /* Check on error of previous branch */ |
404 | if (err) | 404 | if (err) |
405 | goto drop; | 405 | return -EINVAL; |
406 | 406 | ||
407 | /* Extract DAM to the tmp variable */ | 407 | /* Extract DAM to the tmp variable */ |
408 | tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03; | 408 | tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03; |
@@ -417,7 +417,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
417 | tmp); | 417 | tmp); |
418 | 418 | ||
419 | if (err) | 419 | if (err) |
420 | goto drop; | 420 | return -EINVAL; |
421 | } | 421 | } |
422 | } else { | 422 | } else { |
423 | err = uncompress_addr(skb, &hdr.daddr, tmp, daddr, | 423 | err = uncompress_addr(skb, &hdr.daddr, tmp, daddr, |
@@ -425,7 +425,7 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
425 | pr_debug("dest: stateless compression mode %d dest %pI6c\n", | 425 | pr_debug("dest: stateless compression mode %d dest %pI6c\n", |
426 | tmp, &hdr.daddr); | 426 | tmp, &hdr.daddr); |
427 | if (err) | 427 | if (err) |
428 | goto drop; | 428 | return -EINVAL; |
429 | } | 429 | } |
430 | 430 | ||
431 | /* UDP data uncompression */ | 431 | /* UDP data uncompression */ |
@@ -434,16 +434,14 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
434 | const int needed = sizeof(struct udphdr) + sizeof(hdr); | 434 | const int needed = sizeof(struct udphdr) + sizeof(hdr); |
435 | 435 | ||
436 | if (uncompress_udp_header(skb, &uh)) | 436 | if (uncompress_udp_header(skb, &uh)) |
437 | goto drop; | 437 | return -EINVAL; |
438 | 438 | ||
439 | /* replace the compressed UDP head by the uncompressed UDP | 439 | /* replace the compressed UDP head by the uncompressed UDP |
440 | * header | 440 | * header |
441 | */ | 441 | */ |
442 | err = skb_cow(skb, needed); | 442 | err = skb_cow(skb, needed); |
443 | if (unlikely(err)) { | 443 | if (unlikely(err)) |
444 | kfree_skb(skb); | ||
445 | return err; | 444 | return err; |
446 | } | ||
447 | 445 | ||
448 | skb_push(skb, sizeof(struct udphdr)); | 446 | skb_push(skb, sizeof(struct udphdr)); |
449 | skb_reset_transport_header(skb); | 447 | skb_reset_transport_header(skb); |
@@ -455,10 +453,8 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
455 | hdr.nexthdr = UIP_PROTO_UDP; | 453 | hdr.nexthdr = UIP_PROTO_UDP; |
456 | } else { | 454 | } else { |
457 | err = skb_cow(skb, sizeof(hdr)); | 455 | err = skb_cow(skb, sizeof(hdr)); |
458 | if (unlikely(err)) { | 456 | if (unlikely(err)) |
459 | kfree_skb(skb); | ||
460 | return err; | 457 | return err; |
461 | } | ||
462 | } | 458 | } |
463 | 459 | ||
464 | hdr.payload_len = htons(skb->len); | 460 | hdr.payload_len = htons(skb->len); |
@@ -478,9 +474,6 @@ lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, | |||
478 | raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); | 474 | raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr)); |
479 | 475 | ||
480 | return 0; | 476 | return 0; |
481 | drop: | ||
482 | kfree_skb(skb); | ||
483 | return -EINVAL; | ||
484 | } | 477 | } |
485 | EXPORT_SYMBOL_GPL(lowpan_header_decompress); | 478 | EXPORT_SYMBOL_GPL(lowpan_header_decompress); |
486 | 479 | ||
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index eef298d17452..dc23c55f1ab6 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -294,20 +294,20 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, | |||
294 | peer = __peer_lookup_chan(dev, chan); | 294 | peer = __peer_lookup_chan(dev, chan); |
295 | rcu_read_unlock(); | 295 | rcu_read_unlock(); |
296 | if (!peer) | 296 | if (!peer) |
297 | goto drop; | 297 | return -EINVAL; |
298 | 298 | ||
299 | saddr = peer->eui64_addr; | 299 | saddr = peer->eui64_addr; |
300 | daddr = dev->netdev->dev_addr; | 300 | daddr = dev->netdev->dev_addr; |
301 | 301 | ||
302 | /* at least two bytes will be used for the encoding */ | 302 | /* at least two bytes will be used for the encoding */ |
303 | if (skb->len < 2) | 303 | if (skb->len < 2) |
304 | goto drop; | 304 | return -EINVAL; |
305 | 305 | ||
306 | if (lowpan_fetch_skb_u8(skb, &iphc0)) | 306 | if (lowpan_fetch_skb_u8(skb, &iphc0)) |
307 | goto drop; | 307 | return -EINVAL; |
308 | 308 | ||
309 | if (lowpan_fetch_skb_u8(skb, &iphc1)) | 309 | if (lowpan_fetch_skb_u8(skb, &iphc1)) |
310 | goto drop; | 310 | return -EINVAL; |
311 | 311 | ||
312 | return lowpan_header_decompress(skb, netdev, | 312 | return lowpan_header_decompress(skb, netdev, |
313 | saddr, IEEE802154_ADDR_LONG, | 313 | saddr, IEEE802154_ADDR_LONG, |
@@ -315,9 +315,6 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, | |||
315 | IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, | 315 | IEEE802154_ADDR_LONG, EUI64_ADDR_LEN, |
316 | iphc0, iphc1); | 316 | iphc0, iphc1); |
317 | 317 | ||
318 | drop: | ||
319 | kfree_skb(skb); | ||
320 | return -EINVAL; | ||
321 | } | 318 | } |
322 | 319 | ||
323 | static int recv_pkt(struct sk_buff *skb, struct net_device *dev, | 320 | static int recv_pkt(struct sk_buff *skb, struct net_device *dev, |
@@ -370,8 +367,10 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev, | |||
370 | goto drop; | 367 | goto drop; |
371 | 368 | ||
372 | ret = iphc_decompress(local_skb, dev, chan); | 369 | ret = iphc_decompress(local_skb, dev, chan); |
373 | if (ret < 0) | 370 | if (ret < 0) { |
371 | kfree_skb(local_skb); | ||
374 | goto drop; | 372 | goto drop; |
373 | } | ||
375 | 374 | ||
376 | local_skb->protocol = htons(ETH_P_IPV6); | 375 | local_skb->protocol = htons(ETH_P_IPV6); |
377 | local_skb->pkt_type = PACKET_HOST; | 376 | local_skb->pkt_type = PACKET_HOST; |
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 | |||
204 | drop: | ||
205 | kfree_skb(skb); | ||
206 | return -EINVAL; | ||
207 | } | 203 | } |
208 | 204 | ||
209 | static struct sk_buff* | 205 | static 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) { |