diff options
author | Patrick McHardy <kaber@trash.net> | 2007-07-18 05:04:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-07-18 05:04:09 -0400 |
commit | 7d4372b5ae2f891e8bfa96c98d450255f58b4dc1 (patch) | |
tree | bca14a197cdef0057e4008152649b43a42d0daba /drivers/net | |
parent | 99acaeb92fc2d52900f00b8e926d9ad81b6e93bb (diff) |
[PPPOL2TP]: Fix use-after-free
Don't use skb->len after passing it to ip_queue_xmit.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/pppol2tp.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 5891a0fbdc8b..856610f0624e 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c | |||
@@ -824,6 +824,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
824 | struct pppol2tp_session *session; | 824 | struct pppol2tp_session *session; |
825 | struct pppol2tp_tunnel *tunnel; | 825 | struct pppol2tp_tunnel *tunnel; |
826 | struct udphdr *uh; | 826 | struct udphdr *uh; |
827 | unsigned int len; | ||
827 | 828 | ||
828 | error = -ENOTCONN; | 829 | error = -ENOTCONN; |
829 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 830 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
@@ -912,14 +913,15 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
912 | } | 913 | } |
913 | 914 | ||
914 | /* Queue the packet to IP for output */ | 915 | /* Queue the packet to IP for output */ |
916 | len = skb->len; | ||
915 | error = ip_queue_xmit(skb, 1); | 917 | error = ip_queue_xmit(skb, 1); |
916 | 918 | ||
917 | /* Update stats */ | 919 | /* Update stats */ |
918 | if (error >= 0) { | 920 | if (error >= 0) { |
919 | tunnel->stats.tx_packets++; | 921 | tunnel->stats.tx_packets++; |
920 | tunnel->stats.tx_bytes += skb->len; | 922 | tunnel->stats.tx_bytes += len; |
921 | session->stats.tx_packets++; | 923 | session->stats.tx_packets++; |
922 | session->stats.tx_bytes += skb->len; | 924 | session->stats.tx_bytes += len; |
923 | } else { | 925 | } else { |
924 | tunnel->stats.tx_errors++; | 926 | tunnel->stats.tx_errors++; |
925 | session->stats.tx_errors++; | 927 | session->stats.tx_errors++; |
@@ -958,6 +960,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
958 | __wsum csum = 0; | 960 | __wsum csum = 0; |
959 | struct sk_buff *skb2 = NULL; | 961 | struct sk_buff *skb2 = NULL; |
960 | struct udphdr *uh; | 962 | struct udphdr *uh; |
963 | unsigned int len; | ||
961 | 964 | ||
962 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) | 965 | if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) |
963 | goto abort; | 966 | goto abort; |
@@ -1050,14 +1053,15 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
1050 | skb2->dst = sk_dst_get(sk_tun); | 1053 | skb2->dst = sk_dst_get(sk_tun); |
1051 | 1054 | ||
1052 | /* Queue the packet to IP for output */ | 1055 | /* Queue the packet to IP for output */ |
1056 | len = skb2->len; | ||
1053 | rc = ip_queue_xmit(skb2, 1); | 1057 | rc = ip_queue_xmit(skb2, 1); |
1054 | 1058 | ||
1055 | /* Update stats */ | 1059 | /* Update stats */ |
1056 | if (rc >= 0) { | 1060 | if (rc >= 0) { |
1057 | tunnel->stats.tx_packets++; | 1061 | tunnel->stats.tx_packets++; |
1058 | tunnel->stats.tx_bytes += skb2->len; | 1062 | tunnel->stats.tx_bytes += len; |
1059 | session->stats.tx_packets++; | 1063 | session->stats.tx_packets++; |
1060 | session->stats.tx_bytes += skb2->len; | 1064 | session->stats.tx_bytes += len; |
1061 | } else { | 1065 | } else { |
1062 | tunnel->stats.tx_errors++; | 1066 | tunnel->stats.tx_errors++; |
1063 | session->stats.tx_errors++; | 1067 | session->stats.tx_errors++; |