diff options
author | Jason Wang <jasowang@redhat.com> | 2018-03-09 01:50:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-09 12:02:59 -0500 |
commit | 3a4030761ea88ff439030ca98e3094b9900e96b7 (patch) | |
tree | c0d48a1da4ce356c2ce2037ba1b4fc210abba7e6 | |
parent | 303fd71b37fb710b26f5ff5444029d62cfd627bd (diff) |
vhost_net: examine pointer types during un-producing
After commit fc72d1d54dd9 ("tuntap: XDP transmission"), we can
actually queueing XDP pointers in the pointer ring, so we should
examine the pointer type before freeing the pointer.
Fixes: fc72d1d54dd9 ("tuntap: XDP transmission")
Reported-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/tun.c | 3 | ||||
-rw-r--r-- | drivers/vhost/net.c | 2 | ||||
-rw-r--r-- | include/linux/if_tun.h | 4 |
3 files changed, 7 insertions, 2 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 7433bb2e4451..28cfa642e39a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -655,7 +655,7 @@ static struct tun_struct *tun_enable_queue(struct tun_file *tfile) | |||
655 | return tun; | 655 | return tun; |
656 | } | 656 | } |
657 | 657 | ||
658 | static void tun_ptr_free(void *ptr) | 658 | void tun_ptr_free(void *ptr) |
659 | { | 659 | { |
660 | if (!ptr) | 660 | if (!ptr) |
661 | return; | 661 | return; |
@@ -667,6 +667,7 @@ static void tun_ptr_free(void *ptr) | |||
667 | __skb_array_destroy_skb(ptr); | 667 | __skb_array_destroy_skb(ptr); |
668 | } | 668 | } |
669 | } | 669 | } |
670 | EXPORT_SYMBOL_GPL(tun_ptr_free); | ||
670 | 671 | ||
671 | static void tun_queue_purge(struct tun_file *tfile) | 672 | static void tun_queue_purge(struct tun_file *tfile) |
672 | { | 673 | { |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index efb93063fda1..8139bc70ad7d 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -170,7 +170,7 @@ static void vhost_net_buf_unproduce(struct vhost_net_virtqueue *nvq) | |||
170 | if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) { | 170 | if (nvq->rx_ring && !vhost_net_buf_is_empty(rxq)) { |
171 | ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head, | 171 | ptr_ring_unconsume(nvq->rx_ring, rxq->queue + rxq->head, |
172 | vhost_net_buf_get_size(rxq), | 172 | vhost_net_buf_get_size(rxq), |
173 | __skb_array_destroy_skb); | 173 | tun_ptr_free); |
174 | rxq->head = rxq->tail = 0; | 174 | rxq->head = rxq->tail = 0; |
175 | } | 175 | } |
176 | } | 176 | } |
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index c5b0a75a7812..fd00170b494f 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h | |||
@@ -25,6 +25,7 @@ struct ptr_ring *tun_get_tx_ring(struct file *file); | |||
25 | bool tun_is_xdp_buff(void *ptr); | 25 | bool tun_is_xdp_buff(void *ptr); |
26 | void *tun_xdp_to_ptr(void *ptr); | 26 | void *tun_xdp_to_ptr(void *ptr); |
27 | void *tun_ptr_to_xdp(void *ptr); | 27 | void *tun_ptr_to_xdp(void *ptr); |
28 | void tun_ptr_free(void *ptr); | ||
28 | #else | 29 | #else |
29 | #include <linux/err.h> | 30 | #include <linux/err.h> |
30 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
@@ -50,5 +51,8 @@ static inline void *tun_ptr_to_xdp(void *ptr) | |||
50 | { | 51 | { |
51 | return NULL; | 52 | return NULL; |
52 | } | 53 | } |
54 | static inline void tun_ptr_free(void *ptr) | ||
55 | { | ||
56 | } | ||
53 | #endif /* CONFIG_TUN */ | 57 | #endif /* CONFIG_TUN */ |
54 | #endif /* __IF_TUN_H */ | 58 | #endif /* __IF_TUN_H */ |