diff options
author | Li RongQing <roy.qing.li@gmail.com> | 2014-10-15 20:49:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-10-15 23:30:28 -0400 |
commit | ce6502a8f9572179f044a4d62667c4645256d6e4 (patch) | |
tree | a202461eca26813b11236fdb5f8353922504fa89 | |
parent | 4e8febd0a76333875636859e0092a14c1fba49e4 (diff) |
vxlan: fix a use after free in vxlan_encap_bypass
when netif_rx() is done, the netif_rx handled skb maybe be freed,
and should not be used.
Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/vxlan.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 2a51e6e48e1e..faf1bd1f1ecf 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1668,6 +1668,8 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, | |||
1668 | struct pcpu_sw_netstats *tx_stats, *rx_stats; | 1668 | struct pcpu_sw_netstats *tx_stats, *rx_stats; |
1669 | union vxlan_addr loopback; | 1669 | union vxlan_addr loopback; |
1670 | union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip; | 1670 | union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip; |
1671 | struct net_device *dev = skb->dev; | ||
1672 | int len = skb->len; | ||
1671 | 1673 | ||
1672 | tx_stats = this_cpu_ptr(src_vxlan->dev->tstats); | 1674 | tx_stats = this_cpu_ptr(src_vxlan->dev->tstats); |
1673 | rx_stats = this_cpu_ptr(dst_vxlan->dev->tstats); | 1675 | rx_stats = this_cpu_ptr(dst_vxlan->dev->tstats); |
@@ -1691,16 +1693,16 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, | |||
1691 | 1693 | ||
1692 | u64_stats_update_begin(&tx_stats->syncp); | 1694 | u64_stats_update_begin(&tx_stats->syncp); |
1693 | tx_stats->tx_packets++; | 1695 | tx_stats->tx_packets++; |
1694 | tx_stats->tx_bytes += skb->len; | 1696 | tx_stats->tx_bytes += len; |
1695 | u64_stats_update_end(&tx_stats->syncp); | 1697 | u64_stats_update_end(&tx_stats->syncp); |
1696 | 1698 | ||
1697 | if (netif_rx(skb) == NET_RX_SUCCESS) { | 1699 | if (netif_rx(skb) == NET_RX_SUCCESS) { |
1698 | u64_stats_update_begin(&rx_stats->syncp); | 1700 | u64_stats_update_begin(&rx_stats->syncp); |
1699 | rx_stats->rx_packets++; | 1701 | rx_stats->rx_packets++; |
1700 | rx_stats->rx_bytes += skb->len; | 1702 | rx_stats->rx_bytes += len; |
1701 | u64_stats_update_end(&rx_stats->syncp); | 1703 | u64_stats_update_end(&rx_stats->syncp); |
1702 | } else { | 1704 | } else { |
1703 | skb->dev->stats.rx_dropped++; | 1705 | dev->stats.rx_dropped++; |
1704 | } | 1706 | } |
1705 | } | 1707 | } |
1706 | 1708 | ||