The VFIO_DEVICE_SET_IRQS ioctl takes a start and count parameter, both
of which are unsigned.  We attempt to bounds check these, but fail to
account for the case where start is a very large number, allowing
start + count to wrap back into the valid range.  Bounds check both
start and start + count.

Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Alex Williamson <[email protected]>
(cherry picked from commit 904c680c7bf016a8619a045850937427f8d7368c)
---

Applies correctly with fuzz back through 3.6.y.

 drivers/vfio/pci/vfio_pci.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index b28e66c..4a62e12 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -331,6 +331,7 @@ static long vfio_pci_ioctl(void *device_data,
 
                if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) {
                        size_t size;
+                       int max = vfio_pci_get_irq_count(vdev, hdr.index);
 
                        if (hdr.flags & VFIO_IRQ_SET_DATA_BOOL)
                                size = sizeof(uint8_t);
@@ -340,7 +341,7 @@ static long vfio_pci_ioctl(void *device_data,
                                return -EINVAL;
 
                        if (hdr.argsz - minsz < hdr.count * size ||
-                           hdr.count > vfio_pci_get_irq_count(vdev, hdr.index))
+                           hdr.start >= max || hdr.start + hdr.count > max)
                                return -EINVAL;
 
                        data = memdup_user((void __user *)(arg + minsz),

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to