[PPP] generic: Fix receive path data clobbering & non-linear handling

This patch adds missing pskb_may_pull calls to deal with non-linear
packets that may arrive from pppoe or pppol2tp.

It also copies cloned packets before writing over them.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Herbert Xu and committed by David S. Miller 2a38b775 7b797d5b

+25 -19
+25 -19
drivers/net/ppp_generic.c
··· 1525 static void 1526 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) 1527 { 1528 - if (skb->len >= 2) { 1529 #ifdef CONFIG_PPP_MULTILINK 1530 /* XXX do channel-level decompression here */ 1531 if (PPP_PROTO(skb) == PPP_MP) ··· 1577 if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP)) 1578 goto err; 1579 1580 - if (skb_tailroom(skb) < 124) { 1581 /* copy to a new sk_buff with more tailroom */ 1582 ns = dev_alloc_skb(skb->len + 128); 1583 if (ns == 0) { ··· 1648 /* check if the packet passes the pass and active filters */ 1649 /* the filter instructions are constructed assuming 1650 a four-byte PPP header on each packet */ 1651 - *skb_push(skb, 2) = 0; 1652 - if (ppp->pass_filter 1653 - && sk_run_filter(skb, ppp->pass_filter, 1654 - ppp->pass_len) == 0) { 1655 - if (ppp->debug & 1) 1656 - printk(KERN_DEBUG "PPP: inbound frame not passed\n"); 1657 - kfree_skb(skb); 1658 - return; 1659 - } 1660 - if (!(ppp->active_filter 1661 - && sk_run_filter(skb, ppp->active_filter, 1662 - ppp->active_len) == 0)) 1663 - ppp->last_recv = jiffies; 1664 - skb_pull(skb, 2); 1665 - #else 1666 - ppp->last_recv = jiffies; 1667 #endif /* CONFIG_PPP_FILTER */ 1668 1669 if ((ppp->dev->flags & IFF_UP) == 0 1670 || ppp->npmode[npi] != NPMODE_PASS) { ··· 1768 struct channel *ch; 1769 int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; 1770 1771 - if (!pskb_may_pull(skb, mphdrlen) || ppp->mrru == 0) 1772 goto err; /* no good, throw it away */ 1773 1774 /* Decode sequence number and begin/end bits */
··· 1525 static void 1526 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) 1527 { 1528 + if (pskb_may_pull(skb, 2)) { 1529 #ifdef CONFIG_PPP_MULTILINK 1530 /* XXX do channel-level decompression here */ 1531 if (PPP_PROTO(skb) == PPP_MP) ··· 1577 if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP)) 1578 goto err; 1579 1580 + if (skb_tailroom(skb) < 124 || skb_cloned(skb)) { 1581 /* copy to a new sk_buff with more tailroom */ 1582 ns = dev_alloc_skb(skb->len + 128); 1583 if (ns == 0) { ··· 1648 /* check if the packet passes the pass and active filters */ 1649 /* the filter instructions are constructed assuming 1650 a four-byte PPP header on each packet */ 1651 + if (ppp->pass_filter || ppp->active_filter) { 1652 + if (skb_cloned(skb) && 1653 + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 1654 + goto err; 1655 + 1656 + *skb_push(skb, 2) = 0; 1657 + if (ppp->pass_filter 1658 + && sk_run_filter(skb, ppp->pass_filter, 1659 + ppp->pass_len) == 0) { 1660 + if (ppp->debug & 1) 1661 + printk(KERN_DEBUG "PPP: inbound frame " 1662 + "not passed\n"); 1663 + kfree_skb(skb); 1664 + return; 1665 + } 1666 + if (!(ppp->active_filter 1667 + && sk_run_filter(skb, ppp->active_filter, 1668 + ppp->active_len) == 0)) 1669 + ppp->last_recv = jiffies; 1670 + __skb_pull(skb, 2); 1671 + } else 1672 #endif /* CONFIG_PPP_FILTER */ 1673 + ppp->last_recv = jiffies; 1674 1675 if ((ppp->dev->flags & IFF_UP) == 0 1676 || ppp->npmode[npi] != NPMODE_PASS) { ··· 1762 struct channel *ch; 1763 int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; 1764 1765 + if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0) 1766 goto err; /* no good, throw it away */ 1767 1768 /* Decode sequence number and begin/end bits */