Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=91781004b9c029ee55b7aa9ef950a373ba865dc6
Commit:     91781004b9c029ee55b7aa9ef950a373ba865dc6
Parent:     6a9fb9479f2672fa392711735de9e642395c9a14
Author:     James Chapman <[EMAIL PROTECTED]>
AuthorDate: Mon Nov 5 23:32:37 2007 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Nov 7 04:08:56 2007 -0800

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 drivers/net/pppol2tp.c |   25 ++++++++++++++++++-------
 1 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f8904fd..a7556cd 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -488,7 +488,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct 
sk_buff *skb)
 {
        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;
@@ -496,7 +496,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct 
sk_buff *skb)
 
        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));
@@ -509,7 +509,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct 
sk_buff *skb)
        }
 
        /* Point to L2TP header */
-       ptr = skb->data;
+       optr = ptr = skb->data;
 
        /* Get L2TP header flags */
        hdrflags = ntohs(*(__be16*)ptr);
@@ -637,12 +637,14 @@ static int pppol2tp_recv_core(struct sock *sock, struct 
sk_buff *skb)
        /* 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
@@ -652,6 +654,9 @@ static int pppol2tp_recv_core(struct sock *sock, struct 
sk_buff *skb)
         * 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);
 
@@ -709,6 +714,10 @@ discard:
        return 0;
 
 error:
+       /* Put UDP header back */
+       __skb_push(skb, sizeof(struct udphdr));
+
+no_tunnel:
        return 1;
 }
 
@@ -1050,6 +1059,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct 
sk_buff *skb)
        /* 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;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to