[PATCH v2 2/4] virtio_input: validate device-reported multitouch slot count
From: Hari Mishal <hidden>
Date: 2026-07-15 16:43:06
Also in:
lkml, virtualization
Subsystem:
the rest, virtio core, virtio input driver · Maintainers:
Linus Torvalds, "Michael S. Tsirkin", Jason Wang, Gerd Hoffmann
nslots is derived from the ABS_MT_SLOT maximum reported by the virtio
device. A device could report a bogus maximum (e.g. -1) making nslots <=
0, and input_mt_init_slots() can independently fail too (e.g. it rejects
slot counts over 1024). Neither case was handled here, and
input_mt_init_slots() failing took down the whole probe, losing the rest
of the input device over a problem isolated to multitouch.
Instead of failing the probe, warn and disable the ABS_MT_SLOT
capability in either case, and let the rest of the device register
normally. This recovery assumes input_mt_init_slots() is called with
flags == 0: with nonzero flags it can fail after already mutating the
input_dev (e.g. via input_set_abs_params()), which this recovery does
not account for.
Signed-off-by: Hari Mishal <redacted>
---
v2: per review, disable multitouch instead of failing the whole
probe when the reported slot count is invalid or
input_mt_init_slots() otherwise fails.
drivers/virtio/virtio_input.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
index deec24e8e682..786f5150724f 100644
--- a/drivers/virtio/virtio_input.c
+++ b/drivers/virtio/virtio_input.c@@ -312,9 +312,25 @@ static int virtinput_probe(struct virtio_device *vdev) if (test_bit(ABS_MT_SLOT, vi->idev->absbit)) { nslots = input_abs_get_max(vi->idev, ABS_MT_SLOT) + 1; - err = input_mt_init_slots(vi->idev, nslots, 0); - if (err) - goto err_mt_init_slots; + if (nslots <= 0) { + dev_warn(&vdev->dev, + "invalid multitouch slot count %d, disabling multitouch\n", + nslots); + __clear_bit(ABS_MT_SLOT, vi->idev->absbit); + } else { + /* + * flags is 0: input_mt_init_slots() can only fail + * before touching *idev, so the recovery below is + * a full rollback. + */ + err = input_mt_init_slots(vi->idev, nslots, 0); + if (err) { + dev_warn(&vdev->dev, + "failed to init %d multitouch slots (%d), disabling multitouch\n", + nslots, err); + __clear_bit(ABS_MT_SLOT, vi->idev->absbit); + } + } } }
@@ -331,7 +347,6 @@ static int virtinput_probe(struct virtio_device *vdev) spin_lock_irqsave(&vi->lock, flags); vi->ready = false; spin_unlock_irqrestore(&vi->lock, flags); -err_mt_init_slots: input_free_device(vi->idev); err_input_alloc: vdev->config->del_vqs(vdev);
--
2.43.0