From: Al Viro viro@zeniv.linux.org.uk
commit fb4554c2232e44d595920f4d5c66cf8f7d13f9bc upstream.
Descriptor table is a shared resource; two fget() on the same descriptor may return different struct file references. get_tap_ptr_ring() is called after we'd found (and pinned) the socket we'll be using and it tries to find the private tun/tap data structures associated with it. Redoing the lookup by the same file descriptor we'd used to get the socket is racy - we need to same struct file.
Thanks to Jason for spotting a braino in the original variant of patch - I'd missed the use of fd == -1 for disabling backend, and in that case we can end up with sock == NULL and sock != oldsock.
Cc: stable@kernel.org Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Jason Wang jasowang@redhat.com Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [4.14: Account for get_tap_skb_array() instead of get_tap_ptr_ring()] Signed-off-by: Samuel Mendoza-Jonas samjonas@amazon.com --- drivers/vhost/net.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 66212ba07cbc..c41197402d81 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -1047,13 +1047,9 @@ static struct socket *get_raw_socket(int fd) return ERR_PTR(r); }
-static struct skb_array *get_tap_skb_array(int fd) +static struct skb_array *get_tap_skb_array(struct file *file) { struct skb_array *array; - struct file *file = fget(fd); - - if (!file) - return NULL; array = tun_get_skb_array(file); if (!IS_ERR(array)) goto out; @@ -1062,7 +1058,6 @@ static struct skb_array *get_tap_skb_array(int fd) goto out; array = NULL; out: - fput(file); return array; }
@@ -1143,8 +1138,12 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) vhost_net_disable_vq(n, vq); vq->private_data = sock; vhost_net_buf_unproduce(nvq); - if (index == VHOST_NET_VQ_RX) - nvq->rx_array = get_tap_skb_array(fd); + if (index == VHOST_NET_VQ_RX) { + if (sock) + nvq->rx_array = get_tap_skb_array(sock->file); + else + nvq->rx_array = NULL; + } r = vhost_vq_init_access(vq); if (r) goto err_used;
On Tue, Jun 06, 2023 at 11:28:31AM -0700, Samuel Mendoza-Jonas wrote:
From: Al Viro viro@zeniv.linux.org.uk
commit fb4554c2232e44d595920f4d5c66cf8f7d13f9bc upstream.
Descriptor table is a shared resource; two fget() on the same descriptor may return different struct file references. get_tap_ptr_ring() is called after we'd found (and pinned) the socket we'll be using and it tries to find the private tun/tap data structures associated with it. Redoing the lookup by the same file descriptor we'd used to get the socket is racy - we need to same struct file.
Thanks to Jason for spotting a braino in the original variant of patch - I'd missed the use of fd == -1 for disabling backend, and in that case we can end up with sock == NULL and sock != oldsock.
Cc: stable@kernel.org Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Jason Wang jasowang@redhat.com Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
I did not sign off on this patch, where did that come from?
Please be more careful.
thanks,
greg k-h
On Wed, Jun 07, 2023 at 08:35:29PM +0200, Greg Kroah-Hartman wrote:
CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you can confirm the sender and know the content is safe.
On Tue, Jun 06, 2023 at 11:28:31AM -0700, Samuel Mendoza-Jonas wrote:
From: Al Viro viro@zeniv.linux.org.uk
commit fb4554c2232e44d595920f4d5c66cf8f7d13f9bc upstream.
Descriptor table is a shared resource; two fget() on the same descriptor may return different struct file references. get_tap_ptr_ring() is called after we'd found (and pinned) the socket we'll be using and it tries to find the private tun/tap data structures associated with it. Redoing the lookup by the same file descriptor we'd used to get the socket is racy - we need to same struct file.
Thanks to Jason for spotting a braino in the original variant of patch - I'd missed the use of fd == -1 for disabling backend, and in that case we can end up with sock == NULL and sock != oldsock.
Cc: stable@kernel.org Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Jason Wang jasowang@redhat.com Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
I did not sign off on this patch, where did that come from?
Please be more careful.
thanks,
greg k-h
Ah my apologies, that must have come from the commit to the other stable branches.
Thanks, Sam
linux-stable-mirror@lists.linaro.org