diff --git a/devicemodel/hw/pci/virtio/virtio_console.c b/devicemodel/hw/pci/virtio/virtio_console.c index 75f50614e..d3b0fb857 100644 --- a/devicemodel/hw/pci/virtio/virtio_console.c +++ b/devicemodel/hw/pci/virtio/virtio_console.c @@ -392,7 +392,10 @@ virtio_console_notify_tx(void *vdev, struct virtio_vq_info *vq) port = virtio_console_vq_to_port(console, vq); while (vq_has_descs(vq)) { - vq_getchain(vq, &idx, iov, 1, flags); + if (vq_getchain(vq, &idx, iov, 1, flags) < 1) { + pr_err("%s: fail to getchain!\n", __func__); + break; + } if ((port != NULL) && (port->cb != NULL)) port->cb(port, port->arg, iov, 1); @@ -481,6 +484,10 @@ virtio_console_backend_read(int fd __attribute__((unused)), do { n = vq_getchain(vq, &idx, &iov, 1, NULL); + if (n < 1){ + pr_err("%s: fail to getchain!\n", __func__); + break; + } len = readv(be->fd, &iov, n); if (len <= 0) { vq_retchain(vq); diff --git a/devicemodel/hw/pci/virtio/virtio_gpio.c b/devicemodel/hw/pci/virtio/virtio_gpio.c index ed70e2444..110f6bacd 100644 --- a/devicemodel/hw/pci/virtio/virtio_gpio.c +++ b/devicemodel/hw/pci/virtio/virtio_gpio.c @@ -688,7 +688,7 @@ virtio_gpio_notify(void *vdev, struct virtio_vq_info *vq) gpio = (struct virtio_gpio *)vdev; if (vq_has_descs(vq)) { n = vq_getchain(vq, &idx, iov, 2, NULL); - if (n >= 3) { + if (n < 1 || n >= 3) { WPRINTF(("virtio gpio, invalid chain number %d\n", n)); virtio_gpio_abort(vq, idx); return; diff --git a/devicemodel/hw/pci/virtio/virtio_rnd.c b/devicemodel/hw/pci/virtio/virtio_rnd.c index 247142320..2beec5016 100644 --- a/devicemodel/hw/pci/virtio/virtio_rnd.c +++ b/devicemodel/hw/pci/virtio/virtio_rnd.c @@ -322,7 +322,10 @@ virtio_rnd_get_entropy(void *param) pthread_mutex_unlock(&rnd->rx_mtx); do { - vq_getchain(vq, &idx, &iov, 1, NULL); + if (vq_getchain(vq, &idx, &iov, 1, NULL) < 1) { + pr_err("%s: fail to getchain!\n", __func__); + break; + } len = read(rnd->fd, iov.iov_base, iov.iov_len); if (len <= 0) { vq_retchain(vq); diff --git a/devicemodel/include/virtio.h b/devicemodel/include/virtio.h index 5793db382..6581b5cfd 100644 --- a/devicemodel/include/virtio.h +++ b/devicemodel/include/virtio.h @@ -477,8 +477,15 @@ vq_ring_ready(struct virtio_vq_info *vq) static inline bool vq_has_descs(struct virtio_vq_info *vq) { - return (vq_ring_ready(vq) && vq->last_avail != - vq->avail->idx); + bool ret = false; + if (vq_ring_ready(vq) && vq->last_avail != vq->avail->idx) { + if ((uint16_t)((u_int)vq->avail->idx - vq->last_avail) > vq->qsize) + pr_err ("%s: no valid descriptor\n", vq->base->vops->name); + else + ret = true; + } + return ret; + } /**