Lee Jones
2022-Mar-02 07:54 UTC
[PATCH 1/1] vhost: Protect the virtqueue from being cleared whilst still in use
vhost_vsock_handle_tx_kick() already holds the mutex during its call to vhost_get_vq_desc(). All we have to do is take the same lock during virtqueue clean-up and we mitigate the reported issues. Link: https://syzkaller.appspot.com/bug?extid=279432d30d825e63ba00 Cc: <stable at vger.kernel.org> Reported-by: syzbot+adc3cb32385586bec859 at syzkaller.appspotmail.com Signed-off-by: Lee Jones <lee.jones at linaro.org> --- drivers/vhost/vhost.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 59edb5a1ffe28..bbaff6a5e21b8 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -693,6 +693,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) int i; for (i = 0; i < dev->nvqs; ++i) { + mutex_lock(&dev->vqs[i]->mutex); if (dev->vqs[i]->error_ctx) eventfd_ctx_put(dev->vqs[i]->error_ctx); if (dev->vqs[i]->kick) @@ -700,6 +701,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) if (dev->vqs[i]->call_ctx.ctx) eventfd_ctx_put(dev->vqs[i]->call_ctx.ctx); vhost_vq_reset(dev, dev->vqs[i]); + mutex_unlock(&dev->vqs[i]->mutex); } vhost_dev_free_iovecs(dev); if (dev->log_ctx) -- 2.35.1.574.g5d30c73bfb-goog
Stefano Garzarella
2022-Mar-02 09:34 UTC
[PATCH 1/1] vhost: Protect the virtqueue from being cleared whilst still in use
On Wed, Mar 02, 2022 at 07:54:21AM +0000, Lee Jones wrote:>vhost_vsock_handle_tx_kick() already holds the mutex during its call >to vhost_get_vq_desc(). All we have to do is take the same lock >during virtqueue clean-up and we mitigate the reported issues. > >Link: https://syzkaller.appspot.com/bug?extid=279432d30d825e63ba00This issue is similar to [1] that should be already fixed upstream by [2]. However I think this patch would have prevented some issues, because vhost_vq_reset() sets vq->private to NULL, preventing the worker from running. Anyway I think that when we enter in vhost_dev_cleanup() the worker should be already stopped, so it shouldn't be necessary to take the mutex. But in order to prevent future issues maybe it's better to take them, so: Reviewed-by: Stefano Garzarella <sgarzare at redhat.com> [1] https://syzkaller.appspot.com/bug?id=993d8b5e64393ed9e6a70f9ae4de0119c605a822 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a58da53ffd70294ebea8ecd0eb45fd0d74add9f9> >Cc: <stable at vger.kernel.org> >Reported-by: syzbot+adc3cb32385586bec859 at syzkaller.appspotmail.com >Signed-off-by: Lee Jones <lee.jones at linaro.org> >--- > drivers/vhost/vhost.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c >index 59edb5a1ffe28..bbaff6a5e21b8 100644 >--- a/drivers/vhost/vhost.c >+++ b/drivers/vhost/vhost.c >@@ -693,6 +693,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > int i; > > for (i = 0; i < dev->nvqs; ++i) { >+ mutex_lock(&dev->vqs[i]->mutex); > if (dev->vqs[i]->error_ctx) > eventfd_ctx_put(dev->vqs[i]->error_ctx); > if (dev->vqs[i]->kick) >@@ -700,6 +701,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > if (dev->vqs[i]->call_ctx.ctx) > eventfd_ctx_put(dev->vqs[i]->call_ctx.ctx); > vhost_vq_reset(dev, dev->vqs[i]); >+ mutex_unlock(&dev->vqs[i]->mutex); > } > vhost_dev_free_iovecs(dev); > if (dev->log_ctx) >-- >2.35.1.574.g5d30c73bfb-goog >
Michael S. Tsirkin
2022-Mar-02 13:30 UTC
[PATCH 1/1] vhost: Protect the virtqueue from being cleared whilst still in use
On Wed, Mar 02, 2022 at 07:54:21AM +0000, Lee Jones wrote:> vhost_vsock_handle_tx_kick() already holds the mutex during its call > to vhost_get_vq_desc(). All we have to do is take the same lock > during virtqueue clean-up and we mitigate the reported issues. > > Link: https://syzkaller.appspot.com/bug?extid=279432d30d825e63ba00 > > Cc: <stable at vger.kernel.org> > Reported-by: syzbot+adc3cb32385586bec859 at syzkaller.appspotmail.com > Signed-off-by: Lee Jones <lee.jones at linaro.org> > --- > drivers/vhost/vhost.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c > index 59edb5a1ffe28..bbaff6a5e21b8 100644 > --- a/drivers/vhost/vhost.c > +++ b/drivers/vhost/vhost.c > @@ -693,6 +693,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > int i; > > for (i = 0; i < dev->nvqs; ++i) { > + mutex_lock(&dev->vqs[i]->mutex); > if (dev->vqs[i]->error_ctx) > eventfd_ctx_put(dev->vqs[i]->error_ctx); > if (dev->vqs[i]->kick) > @@ -700,6 +701,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > if (dev->vqs[i]->call_ctx.ctx) > eventfd_ctx_put(dev->vqs[i]->call_ctx.ctx); > vhost_vq_reset(dev, dev->vqs[i]); > + mutex_unlock(&dev->vqs[i]->mutex); > }So this is a mitigation plan but the bug is still there though we don't know exactly what it is. I would prefer adding something like WARN_ON(mutex_is_locked(vqs[i]->mutex) here - does this make sense?> vhost_dev_free_iovecs(dev); > if (dev->log_ctx) > -- > 2.35.1.574.g5d30c73bfb-goog
Michael S. Tsirkin
2022-Mar-04 05:00 UTC
[PATCH 1/1] vhost: Protect the virtqueue from being cleared whilst still in use
On Wed, Mar 02, 2022 at 07:54:21AM +0000, Lee Jones wrote:> vhost_vsock_handle_tx_kick() already holds the mutex during its call > to vhost_get_vq_desc(). All we have to do is take the same lock > during virtqueue clean-up and we mitigate the reported issues. > > Link: https://syzkaller.appspot.com/bug?extid=279432d30d825e63ba00 > > Cc: <stable at vger.kernel.org> > Reported-by: syzbot+adc3cb32385586bec859 at syzkaller.appspotmail.com > Signed-off-by: Lee Jones <lee.jones at linaro.org>So combine with the warning patch and update description with the comment I posted, explaining it's more a just in case thing.> --- > drivers/vhost/vhost.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c > index 59edb5a1ffe28..bbaff6a5e21b8 100644 > --- a/drivers/vhost/vhost.c > +++ b/drivers/vhost/vhost.c > @@ -693,6 +693,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > int i; > > for (i = 0; i < dev->nvqs; ++i) { > + mutex_lock(&dev->vqs[i]->mutex); > if (dev->vqs[i]->error_ctx) > eventfd_ctx_put(dev->vqs[i]->error_ctx); > if (dev->vqs[i]->kick) > @@ -700,6 +701,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > if (dev->vqs[i]->call_ctx.ctx) > eventfd_ctx_put(dev->vqs[i]->call_ctx.ctx); > vhost_vq_reset(dev, dev->vqs[i]); > + mutex_unlock(&dev->vqs[i]->mutex); > } > vhost_dev_free_iovecs(dev); > if (dev->log_ctx) > -- > 2.35.1.574.g5d30c73bfb-goog
Michael S. Tsirkin
2022-Mar-04 16:48 UTC
[PATCH 1/1] vhost: Protect the virtqueue from being cleared whilst still in use
On Wed, Mar 02, 2022 at 07:54:21AM +0000, Lee Jones wrote:> vhost_vsock_handle_tx_kick() already holds the mutex during its call > to vhost_get_vq_desc(). All we have to do is take the same lock > during virtqueue clean-up and we mitigate the reported issues. > > Link: https://syzkaller.appspot.com/bug?extid=279432d30d825e63ba00 > > Cc: <stable at vger.kernel.org> > Reported-by: syzbot+adc3cb32385586bec859 at syzkaller.appspotmail.com > Signed-off-by: Lee Jones <lee.jones at linaro.org>OK so please post series with this and the warning cleaned up comments and commit logs explaining that this is just to make debugging easier in case we have issues in the future, it's not a bugfix.> --- > drivers/vhost/vhost.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c > index 59edb5a1ffe28..bbaff6a5e21b8 100644 > --- a/drivers/vhost/vhost.c > +++ b/drivers/vhost/vhost.c > @@ -693,6 +693,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > int i; > > for (i = 0; i < dev->nvqs; ++i) { > + mutex_lock(&dev->vqs[i]->mutex); > if (dev->vqs[i]->error_ctx) > eventfd_ctx_put(dev->vqs[i]->error_ctx); > if (dev->vqs[i]->kick) > @@ -700,6 +701,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) > if (dev->vqs[i]->call_ctx.ctx) > eventfd_ctx_put(dev->vqs[i]->call_ctx.ctx); > vhost_vq_reset(dev, dev->vqs[i]); > + mutex_unlock(&dev->vqs[i]->mutex); > } > vhost_dev_free_iovecs(dev); > if (dev->log_ctx) > -- > 2.35.1.574.g5d30c73bfb-goog