From c98857b3fab53c114a6f9e9a40c35791af2639af Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Thu, 10 Feb 2022 11:09:36 +0800 Subject: [PATCH] virtio: check descriptor numbers Check if the vring num is normal in virtio_save(), and add LOG the vm push the wrong viring num down through writing IO Port. Signed-off-by: Jinhua Cao --- virtio-check-descriptor-numbers.patch | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 virtio-check-descriptor-numbers.patch diff --git a/virtio-check-descriptor-numbers.patch b/virtio-check-descriptor-numbers.patch new file mode 100644 index 0000000..ea38103 --- /dev/null +++ b/virtio-check-descriptor-numbers.patch @@ -0,0 +1,52 @@ +From 9e04e1c6a7a12e3e1d0a8a7cf07f441597a1dbb7 Mon Sep 17 00:00:00 2001 +From: Jinhua Cao +Date: Thu, 10 Feb 2022 11:09:36 +0800 +Subject: [PATCH] virtio: check descriptor numbers + +Check if the vring num is normal in virtio_save(), and add LOG +the vm push the wrong viring num down through writing IO Port. + +Signed-off-by: Jinhua Cao +--- + hw/virtio/virtio.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index 03afa36e99..007f4c9e26 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -2860,6 +2860,22 @@ static const VMStateDescription vmstate_virtio = { + } + }; + ++static void check_vring_avail_num(VirtIODevice *vdev, int index) ++{ ++ uint16_t nheads; ++ ++ /* Check it isn't doing strange things with descriptor numbers. */ ++ nheads = vring_avail_idx(&vdev->vq[index]) - vdev->vq[index].last_avail_idx; ++ if (nheads > vdev->vq[index].vring.num) { ++ qemu_log("VQ %d size 0x%x Guest index 0x%x " ++ "inconsistent with Host index 0x%x: " ++ "delta 0x%x\n", ++ index, vdev->vq[index].vring.num, ++ vring_avail_idx(&vdev->vq[index]), ++ vdev->vq[index].last_avail_idx, nheads); ++ } ++} ++ + int virtio_save(VirtIODevice *vdev, QEMUFile *f) + { + BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); +@@ -2890,6 +2906,8 @@ int virtio_save(VirtIODevice *vdev, QEMUFile *f) + if (vdev->vq[i].vring.num == 0) + break; + ++ check_vring_avail_num(vdev, i); ++ + qemu_put_be32(f, vdev->vq[i].vring.num); + if (k->has_variable_vring_alignment) { + qemu_put_be32(f, vdev->vq[i].vring.align); +-- +2.27.0 +