aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-07-18 05:04:09 -0400
committerDavid S. Miller <davem@davemloft.net>2007-07-18 05:04:09 -0400
commit7d4372b5ae2f891e8bfa96c98d450255f58b4dc1 (patch)
treebca14a197cdef0057e4008152649b43a42d0daba
parent99acaeb92fc2d52900f00b8e926d9ad81b6e93bb (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>
-rw-r--r--drivers/net/pppol2tp.c12
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++;