aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2008-05-19 17:10:01 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-19 17:10:01 -0400
commit090c48d3dd5ea90b37350334aaed9a93b0c1e0a1 (patch)
treeb912bf1bd1519bfcccd36e0927a7adf43f34587b
parent066b2118976e6e7cc50eed39e2747c75343a23c4 (diff)
l2tp: avoid skb truesize bug if headroom is increased
A user reported seeing occasional bugs such as the following when using the L2TP driver. SKB BUG: Invalid truesize (272) len=72, sizeof(sk_buff)=208 When L2TP adds its header in the transmit path, it might need to increase the headroom of the skb. In some cases, the increased headroom trips a kernel bug when the skb is freed because the skb has grown beyond its truesize value. The fix is to increase the truesize by the amount of headroom added, after orphaning the skb. While here, fix a misleading comment. Thanks to Iouri Kharon <bc-info@styx.cabel.net> for the initial report and testing the fix. Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/pppol2tp.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index 79359919335b..8db342f2fdc9 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -980,6 +980,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
980 __wsum csum = 0; 980 __wsum csum = 0;
981 struct udphdr *uh; 981 struct udphdr *uh;
982 unsigned int len; 982 unsigned int len;
983 int old_headroom;
984 int new_headroom;
983 985
984 if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) 986 if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
985 goto abort; 987 goto abort;
@@ -1001,16 +1003,18 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1001 1003
1002 /* Check that there's enough headroom in the skb to insert IP, 1004 /* Check that there's enough headroom in the skb to insert IP,
1003 * UDP and L2TP and PPP headers. If not enough, expand it to 1005 * UDP and L2TP and PPP headers. If not enough, expand it to
1004 * make room. Note that a new skb (or a clone) is 1006 * make room. Adjust truesize.
1005 * allocated. If we return an error from this point on, make
1006 * sure we free the new skb but do not free the original skb
1007 * since that is done by the caller for the error case.
1008 */ 1007 */
1009 headroom = NET_SKB_PAD + sizeof(struct iphdr) + 1008 headroom = NET_SKB_PAD + sizeof(struct iphdr) +
1010 sizeof(struct udphdr) + hdr_len + sizeof(ppph); 1009 sizeof(struct udphdr) + hdr_len + sizeof(ppph);
1010 old_headroom = skb_headroom(skb);
1011 if (skb_cow_head(skb, headroom)) 1011 if (skb_cow_head(skb, headroom))
1012 goto abort; 1012 goto abort;
1013 1013
1014 new_headroom = skb_headroom(skb);
1015 skb_orphan(skb);
1016 skb->truesize += new_headroom - old_headroom;
1017
1014 /* Setup PPP header */ 1018 /* Setup PPP header */
1015 __skb_push(skb, sizeof(ppph)); 1019 __skb_push(skb, sizeof(ppph));
1016 skb->data[0] = ppph[0]; 1020 skb->data[0] = ppph[0];
@@ -1065,7 +1069,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
1065 /* Get routing info from the tunnel socket */ 1069 /* Get routing info from the tunnel socket */
1066 dst_release(skb->dst); 1070 dst_release(skb->dst);
1067 skb->dst = dst_clone(__sk_dst_get(sk_tun)); 1071 skb->dst = dst_clone(__sk_dst_get(sk_tun));
1068 skb_orphan(skb);
1069 skb->sk = sk_tun; 1072 skb->sk = sk_tun;
1070 1073
1071 /* Queue the packet to IP for output */ 1074 /* Queue the packet to IP for output */