[PATCH] Fix PPP async regression

STALE8511d

2 messages, 2 authors, 2003-06-28 · open the first message on its own page

[PATCH] Fix PPP async regression

From: Stephen Hemminger <hidden>
Date: 2003-06-27 23:28:18

Please apply this patch, it fixes the PPP over async regression that the PPPoE
changes caused.  Basically, PPP puts a zero length skbuff in the receive queue
as an error token, and the last change caused that to get flushed as bad data.

Thanks to Diego Calleja García , Matthew Harrell for validating this.

diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c	Fri Jun 27 16:13:28 2003
+++ b/drivers/net/ppp_generic.c	Fri Jun 27 16:13:28 2003
@@ -1348,16 +1348,9 @@
 	struct channel *pch = chan->ppp;
 	int proto;
 
-	if (pch == 0)
-		goto drop;
-
-	/* need to have PPP header */
-	if (!pskb_may_pull(skb, 2)) {
-		if (pch->ppp) {
-			++pch->ppp->stats.rx_length_errors;
-			ppp_receive_error(pch->ppp);
-		}
-		goto drop;
+	if (pch == 0 || skb->len == 0) {
+		kfree_skb(skb);
+		return;
 	}
 	
 	proto = PPP_PROTO(skb);
@@ -1374,10 +1367,6 @@
 		ppp_do_recv(pch->ppp, skb, pch);
 	}
 	read_unlock_bh(&pch->upl);
-	return;
- drop:
-	kfree_skb(skb);
-	return;
 }
 
 /* Put a 0-length skb in the receive queue as an error indication */
@@ -1409,13 +1398,23 @@
 static void
 ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 {
+	if (skb->len >= 2) {
 #ifdef CONFIG_PPP_MULTILINK
-	/* XXX do channel-level decompression here */
-	if (PPP_PROTO(skb) == PPP_MP)
-		ppp_receive_mp_frame(ppp, skb, pch);
-	else
+		/* XXX do channel-level decompression here */
+		if (PPP_PROTO(skb) == PPP_MP)
+			ppp_receive_mp_frame(ppp, skb, pch);
+		else
 #endif /* CONFIG_PPP_MULTILINK */
-		ppp_receive_nonmp_frame(ppp, skb);
+			ppp_receive_nonmp_frame(ppp, skb);
+		return;
+	}
+
+	if (skb->len > 0)
+		/* note: a 0-length skb is used as an error indication */
+		++ppp->stats.rx_length_errors;
+
+	kfree_skb(skb);
+	ppp_receive_error(ppp);
 }
 
 static void
@@ -1448,7 +1447,7 @@
 		if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP))
 			goto err;
 
-		if (skb_tailroom(skb) < 124 || skb_is_nonlinear(skb) ) {
+		if (skb_tailroom(skb) < 124) {
 			/* copy to a new sk_buff with more tailroom */
 			ns = dev_alloc_skb(skb->len + 128);
 			if (ns == 0) {
@@ -1460,6 +1459,9 @@
 			kfree_skb(skb);
 			skb = ns;
 		}
+		else if (!pskb_may_pull(skb, skb->len))
+			goto err;
+
 		len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2);
 		if (len <= 0) {
 			printk(KERN_DEBUG "PPP: VJ decompression error\n");
@@ -2033,12 +2035,12 @@
 static void
 ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound)
 {
-	unsigned char *dp = skb->data + 2;
+	unsigned char *dp;
 	int len;
 
-	if (!pskb_may_pull(skb, CCP_HDRLEN + 2)
-	    || skb->len < (len = CCP_LENGTH(dp)) + 2)
-		return;		/* too short */
+	if (!pskb_may_pull(skb, CCP_HDRLEN + 2))
+		return;	/* no header */
+	dp = skb->data + 2;
 
 	switch (CCP_CODE(dp)) {
 	case CCP_CONFREQ:
@@ -2071,10 +2073,8 @@
 	case CCP_CONFACK:
 		if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN)
 			break;
-
-		if (!pskb_may_pull(skb, len))
-			break;
-
+		if (!pskb_may_pull(skb, len = CCP_LENGTH(dp)) + 2)
+			return;		/* too short */
 		dp += CCP_HDRLEN;
 		len -= CCP_HDRLEN;
 		if (len < CCP_OPT_MINLEN || len < CCP_OPT_LENGTH(dp))

Re: [PATCH] Fix PPP async regression

From: David S. Miller <hidden>
Date: 2003-06-28 07:20:55

   From: Stephen Hemminger [off-list ref]
   Date: Fri, 27 Jun 2003 16:28:18 -0700

   Please apply this patch, it fixes the PPP over async regression
   that the PPPoE changes caused.

Thanks a lot Stephen, applied.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help