Skip to content

Commit

Permalink
virtio(4): change members of struct vring_desc_extra before free a slot
Browse files Browse the repository at this point in the history
This prevents the following race condition.
1. Thread-A: calls virtio_dequeue_commit() and
             puts a slot into free descriptor chain in vq_free_slot()
2. Thread-B: calls virtio_enqueue_prep() and get the slot stored by Thread-A
3. Thread-B: calls virtio_enqueue_reserve() and
             changes desc_base and desc_free_idx for the slot
4. Thread-A: changes the same members updated by Thread-B

reported by hannken, thanks.
  • Loading branch information
yamaguchi authored and yamaguchi committed Apr 21, 2023
1 parent df34ba1 commit 48bba19
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions sys/dev/pci/virtio.c
@@ -1,4 +1,4 @@
/* $NetBSD: virtio.c,v 1.77 2023/04/19 00:40:30 yamaguchi Exp $ */
/* $NetBSD: virtio.c,v 1.78 2023/04/21 02:17:32 yamaguchi Exp $ */

/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -28,7 +28,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.77 2023/04/19 00:40:30 yamaguchi Exp $");
__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.78 2023/04/21 02:17:32 yamaguchi Exp $");

#include <sys/param.h>
#include <sys/systm.h>
Expand Down Expand Up @@ -1258,12 +1258,12 @@ virtio_enqueue_abort(struct virtio_softc *sc, struct virtqueue *vq, int slot)
{
struct vring_desc_extra *vdx;

vq_free_slot(sc, vq, slot);

vdx = &vq->vq_descx[slot];
vdx->desc_free_idx = VRING_DESC_CHAIN_END;
vdx->desc_base = NULL;

vq_free_slot(sc, vq, slot);

return 0;
}

Expand Down Expand Up @@ -1308,12 +1308,12 @@ virtio_dequeue_commit(struct virtio_softc *sc, struct virtqueue *vq, int slot)
{
struct vring_desc_extra *vdx;

vq_free_slot(sc, vq, slot);

vdx = &vq->vq_descx[slot];
vdx->desc_base = NULL;
vdx->desc_free_idx = VRING_DESC_CHAIN_END;

vq_free_slot(sc, vq, slot);

return 0;
}

Expand Down

0 comments on commit 48bba19

Please sign in to comment.