Commit 4b7fd2e6 authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by David S. Miller

virtio_net: fix use after free

commit 0b725a2c
    net: Remove ndo_xmit_flush netdev operation, use signalling instead.

added code that looks at skb->xmit_more after the skb has
been put in TX VQ. Since some paths process the ring and free the skb
immediately, this can cause use after free.

Fix by storing xmit_more in a local variable.

Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 28b5f058
...@@ -920,6 +920,8 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -920,6 +920,8 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
int qnum = skb_get_queue_mapping(skb); int qnum = skb_get_queue_mapping(skb);
struct send_queue *sq = &vi->sq[qnum]; struct send_queue *sq = &vi->sq[qnum];
int err; int err;
struct netdev_queue *txq = netdev_get_tx_queue(dev, qnum);
bool kick = !skb->xmit_more;
/* Free up any pending old buffers before queueing new ones. */ /* Free up any pending old buffers before queueing new ones. */
free_old_xmit_skbs(sq); free_old_xmit_skbs(sq);
...@@ -956,7 +958,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -956,7 +958,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
} }
} }
if (__netif_subqueue_stopped(dev, qnum) || !skb->xmit_more) if (kick || netif_xmit_stopped(txq))
virtqueue_kick(sq->vq); virtqueue_kick(sq->vq);
return NETDEV_TX_OK; return NETDEV_TX_OK;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment