[lvc-project] [PATCH v2] input: sur40: fix error recovery in sur40_probe()
Dmitry Antipov
dmantipov at yandex.ru
Mon Aug 10 18:35:09 MSK 2026
Since an input device which has passed 'input_register_device()' should
be released with 'input_unregister_device()', adjust 'sur40_probe()'
to do so and call 'input_free_device()' to handle device register error
only. To avoid V4L2 memory leak, ensure that 'v4l2_ctrl_handler_free()'
is called on all error handling paths, including the one after
'video_register_device()' failure.
Reported-by: syzbot+2a123f6269da57ffefaa at syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2a123f6269da57ffefaa
Fixes: 08b936012964 ("Input: sur40 - switch to using polled mode of input devices")
Signed-off-by: Dmitry Antipov <dmantipov at yandex.ru>
---
v2: setup sur40 input device pointer after 'input_register_device()' and
adjust error handling path to ensure that 'input_unregister_device()'
is always called for a registered device only (Vasileios)
---
drivers/input/touchscreen/sur40.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index fe63d53d56db..35a946979cb0 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -713,7 +713,6 @@ static int sur40_probe(struct usb_interface *interface,
sur40->usbdev = usbdev;
sur40->dev = &interface->dev;
- sur40->input = input;
/* use the bulk-in endpoint tested above */
sur40->bulk_in_size = usb_endpoint_maxp(endpoint);
@@ -733,6 +732,9 @@ static int sur40_probe(struct usb_interface *interface,
goto err_free_buffer;
}
+ /* now we have a completely initialized input device */
+ sur40->input = input;
+
/* register the video master device */
snprintf(sur40->v4l2.name, sizeof(sur40->v4l2.name), "%s", DRIVER_LONG);
error = v4l2_device_register(sur40->dev, &sur40->v4l2);
@@ -786,9 +788,8 @@ static int sur40_probe(struct usb_interface *interface,
if (sur40->hdl.error) {
dev_err(&interface->dev,
"Unable to register video controls.");
- v4l2_ctrl_handler_free(&sur40->hdl);
error = sur40->hdl.error;
- goto err_unreg_v4l2;
+ goto err_unreg_ctrl;
}
error = video_register_device(&sur40->vdev, VFL_TYPE_TOUCH, -1);
@@ -806,12 +807,17 @@ static int sur40_probe(struct usb_interface *interface,
err_unreg_video:
video_unregister_device(&sur40->vdev);
+err_unreg_ctrl:
+ v4l2_ctrl_handler_free(&sur40->hdl);
err_unreg_v4l2:
v4l2_device_unregister(&sur40->v4l2);
err_free_buffer:
kfree(sur40->bulk_in_buffer);
err_free_input:
- input_free_device(input);
+ if (sur40->input)
+ input_unregister_device(input);
+ else
+ input_free_device(input);
err_free_dev:
kfree(sur40);
--
2.55.0
More information about the lvc-project
mailing list