diff options
| -rw-r--r-- | drivers/net/ppp_generic.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 6e281bc825e5..75e8903c3754 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
| @@ -1567,13 +1567,22 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 1567 | struct channel *pch = chan->ppp; | 1567 | struct channel *pch = chan->ppp; |
| 1568 | int proto; | 1568 | int proto; |
| 1569 | 1569 | ||
| 1570 | if (!pch || skb->len == 0) { | 1570 | if (!pch) { |
| 1571 | kfree_skb(skb); | 1571 | kfree_skb(skb); |
| 1572 | return; | 1572 | return; |
| 1573 | } | 1573 | } |
| 1574 | 1574 | ||
| 1575 | proto = PPP_PROTO(skb); | ||
| 1576 | read_lock_bh(&pch->upl); | 1575 | read_lock_bh(&pch->upl); |
| 1576 | if (!pskb_may_pull(skb, 2)) { | ||
| 1577 | kfree_skb(skb); | ||
| 1578 | if (pch->ppp) { | ||
| 1579 | ++pch->ppp->dev->stats.rx_length_errors; | ||
| 1580 | ppp_receive_error(pch->ppp); | ||
| 1581 | } | ||
| 1582 | goto done; | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | proto = PPP_PROTO(skb); | ||
| 1577 | if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) { | 1586 | if (!pch->ppp || proto >= 0xc000 || proto == PPP_CCPFRAG) { |
| 1578 | /* put it on the channel queue */ | 1587 | /* put it on the channel queue */ |
| 1579 | skb_queue_tail(&pch->file.rq, skb); | 1588 | skb_queue_tail(&pch->file.rq, skb); |
| @@ -1585,6 +1594,8 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 1585 | } else { | 1594 | } else { |
| 1586 | ppp_do_recv(pch->ppp, skb, pch); | 1595 | ppp_do_recv(pch->ppp, skb, pch); |
| 1587 | } | 1596 | } |
| 1597 | |||
| 1598 | done: | ||
| 1588 | read_unlock_bh(&pch->upl); | 1599 | read_unlock_bh(&pch->upl); |
| 1589 | } | 1600 | } |
| 1590 | 1601 | ||
| @@ -1617,7 +1628,8 @@ ppp_input_error(struct ppp_channel *chan, int code) | |||
| 1617 | static void | 1628 | static void |
| 1618 | ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | 1629 | ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) |
| 1619 | { | 1630 | { |
| 1620 | if (pskb_may_pull(skb, 2)) { | 1631 | /* note: a 0-length skb is used as an error indication */ |
| 1632 | if (skb->len > 0) { | ||
| 1621 | #ifdef CONFIG_PPP_MULTILINK | 1633 | #ifdef CONFIG_PPP_MULTILINK |
| 1622 | /* XXX do channel-level decompression here */ | 1634 | /* XXX do channel-level decompression here */ |
| 1623 | if (PPP_PROTO(skb) == PPP_MP) | 1635 | if (PPP_PROTO(skb) == PPP_MP) |
| @@ -1625,15 +1637,10 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
| 1625 | else | 1637 | else |
| 1626 | #endif /* CONFIG_PPP_MULTILINK */ | 1638 | #endif /* CONFIG_PPP_MULTILINK */ |
| 1627 | ppp_receive_nonmp_frame(ppp, skb); | 1639 | ppp_receive_nonmp_frame(ppp, skb); |
| 1628 | return; | 1640 | } else { |
| 1641 | kfree_skb(skb); | ||
| 1642 | ppp_receive_error(ppp); | ||
| 1629 | } | 1643 | } |
| 1630 | |||
| 1631 | if (skb->len > 0) | ||
| 1632 | /* note: a 0-length skb is used as an error indication */ | ||
| 1633 | ++ppp->dev->stats.rx_length_errors; | ||
| 1634 | |||
| 1635 | kfree_skb(skb); | ||
| 1636 | ppp_receive_error(ppp); | ||
| 1637 | } | 1644 | } |
| 1638 | 1645 | ||
| 1639 | static void | 1646 | static void |
