[PATCH v2 2/4] virtio_input: validate device-reported multitouch slot count
From: Hari Mishal
Date: Wed Jul 15 2026 - 12:48:29 EST
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 <harimishal1@xxxxxxxxx>
---
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