login
Header Space

 
 

[patch 07/16] Fix L2TP oopses.

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <linux-kernel@...>, <stable@...>
Cc: Justin Forbes <jmforbes@...>, Zwane Mwaikambo <zwane@...>, Theodore Ts'o <tytso@...>, Randy Dunlap <rdunlap@...>, Dave Jones <davej@...>, Chuck Wolber <chuckw@...>, Chris Wedgwood <reviews@...>, Michael Krufky <mkrufky@...>, Chuck Ebbert <cebbert@...>, Domenico Andreoli <cavokz@...>, <torvalds@...>, <akpm@...>, <alan@...>, <bunk@...>, James Chapman <jchapman@...>, David S. Miller <davem@...>
Date: Thursday, November 15, 2007 - 2:40 am

-stable review patch.  If anyone has any objections, please let us know.

------------------
From: James Chapman <jchapman@katalix.com>

changeset 91781004b9c029ee55b7aa9ef950a373ba865dc6 in mainline.

[PPP]: L2TP: Fix oops in transmit and receive paths

Changes made on 18-sep to fix skb handling in the pppol2tp driver
broke the transmit and receive paths. Users are only running into this
now because distros are now using 2.6.23 and I must have messed up
when I tested the change.

For receive, we now do our own calculation of how much to pull from
the skb (variable length L2TP header) rather than using
skb_transport_offset(). Also, if the skb isn't a data packet, it must
be passed back to UDP with skb->data pointing to the UDP header.

For transmit, make sure skb->sk is set up because ip_queue_xmit()
needs it.

Signed-off-by: James Chapman <jchapman@katalix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/net/pppol2tp.c |   25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -487,7 +487,7 @@ static int pppol2tp_recv_core(struct soc
 {
 	struct pppol2tp_session *session = NULL;
 	struct pppol2tp_tunnel *tunnel;
-	unsigned char *ptr;
+	unsigned char *ptr, *optr;
 	u16 hdrflags;
 	u16 tunnel_id, session_id;
 	int length;
@@ -495,7 +495,7 @@ static int pppol2tp_recv_core(struct soc
 
 	tunnel = pppol2tp_sock_to_tunnel(sock);
 	if (tunnel == NULL)
-		goto error;
+		goto no_tunnel;
 
 	/* UDP always verifies the packet length. */
 	__skb_pull(skb, sizeof(struct udphdr));
@@ -508,7 +508,7 @@ static int pppol2tp_recv_core(struct soc
 	}
 
 	/* Point to L2TP header */
-	ptr = skb->data;
+	optr = ptr = skb->data;
 
 	/* Get L2TP header flags */
 	hdrflags = ntohs(*(__be16*)ptr);
@@ -636,12 +636,14 @@ static int pppol2tp_recv_core(struct soc
 	/* If offset bit set, skip it. */
 	if (hdrflags & L2TP_HDRFLAG_O) {
 		offset = ntohs(*(__be16 *)ptr);
-		skb->transport_header += 2 + offset;
-		if (!pskb_may_pull(skb, skb_transport_offset(skb) + 2))
-			goto discard;
+		ptr += 2 + offset;
 	}
 
-	__skb_pull(skb, skb_transport_offset(skb));
+	offset = ptr - optr;
+	if (!pskb_may_pull(skb, offset))
+		goto discard;
+
+	__skb_pull(skb, offset);
 
 	/* Skip PPP header, if present.	 In testing, Microsoft L2TP clients
 	 * don't send the PPP header (PPP header compression enabled), but
@@ -651,6 +653,9 @@ static int pppol2tp_recv_core(struct soc
 	 * Note that skb->data[] isn't dereferenced from a u16 ptr here since
 	 * the field may be unaligned.
 	 */
+	if (!pskb_may_pull(skb, 2))
+		goto discard;
+
 	if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03))
 		skb_pull(skb, 2);
 
@@ -708,6 +713,10 @@ discard:
 	return 0;
 
 error:
+	/* Put UDP header back */
+	__skb_push(skb, sizeof(struct udphdr));
+
+no_tunnel:
 	return 1;
 }
 
@@ -1049,6 +1058,8 @@ static int pppol2tp_xmit(struct ppp_chan
 	/* Get routing info from the tunnel socket */
 	dst_release(skb->dst);
 	skb->dst = sk_dst_get(sk_tun);
+	skb_orphan(skb);
+	skb->sk = sk_tun;
 
 	/* Queue the packet to IP for output */
 	len = skb->len;

-- 
-
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[patch 14/16] ipw2100: send WEXT scan events, Greg KH, (Thu Nov 15, 2:41 am)
[patch 09/16] skge: XM PHY handling fixes, Greg KH, (Thu Nov 15, 2:40 am)
[patch 10/16] sky2: status ring race fix, Greg KH, (Thu Nov 15, 2:40 am)
[patch 03/16] ehea: 64K page kernel support fix, Greg KH, (Thu Nov 15, 2:40 am)
Re: [patch 08/16] skge: fix ram buffer size calculation, Linus Torvalds, (Thu Nov 15, 12:11 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Linus Torvalds, (Thu Nov 15, 12:48 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Heikki Orsila, (Fri Nov 16, 5:03 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Stephen Hemminger, (Thu Nov 15, 12:27 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Heikki Orsila, (Thu Nov 15, 5:57 pm)
Re: [patch 08/16] skge: fix ram buffer size calculation, Linus Torvalds, (Thu Nov 15, 12:50 pm)
[patch 04/16] forcedeth msi bugfix, Greg KH, (Thu Nov 15, 2:40 am)
[patch 07/16] Fix L2TP oopses., Greg KH, (Thu Nov 15, 2:40 am)
[patch 05/16] forcedeth: add MCP77 device IDs, Greg KH, (Thu Nov 15, 2:40 am)
[patch 02/16] libertas: fix endianness breakage, Greg KH, (Thu Nov 15, 2:39 am)
[patch 01/16] libertas: more endianness breakage, Greg KH, (Thu Nov 15, 2:39 am)
speck-geostationary