[PATCH 1/2] wifi: carl9170: Revert "carl9170: devres-ing input_allocate_device"
From: Dmitry Torokhov
Date: Thu Oct 01 2026 - 00:49:52 EST
This reverts commit 87ddb2fc29f10cf689ff0dfb88a19b7d3687006b.
carl9170_register() is invoked asynchronously from the
request_firmware_nowait() callback after carl9170_usb_probe() has
already returned, and carl9170_usb_disconnect() calls
carl9170_unregister() followed immediately by carl9170_free(), which
frees struct ar9170 (including ar->wps.name and ar->wps.phys).
Allocating the WPS button input device via
devm_input_allocate_device(&ar->udev->dev) ties its unregistration to
the parent struct usb_device rather than the driver lifecycle. Even if
it were tied to &ar->intf->dev, devres_release_all() runs after
carl9170_usb_disconnect() has already freed struct ar9170 and
unregistered the parent wiphy device. Consequently, the input device
remains registered on input_dev_list with input->name and input->phys
pointing into freed memory, causing a use-after-free when reading
/proc/bus/input/devices or when generating the KOBJ_REMOVE uevent on
unregistration.
Fixes: 87ddb2fc29f1 ("carl9170: devres-ing input_allocate_device")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@xxxxxxxxx>
---
drivers/net/wireless/ath/carl9170/main.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 61c7a1288743..702b6d113b18 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1500,7 +1500,7 @@ static int carl9170_register_wps_button(struct ar9170 *ar)
if (!(ar->features & CARL9170_WPS_BUTTON))
return 0;
- input = devm_input_allocate_device(&ar->udev->dev);
+ input = input_allocate_device();
if (!input)
return -ENOMEM;
@@ -1518,8 +1518,10 @@ static int carl9170_register_wps_button(struct ar9170 *ar)
input_set_capability(input, EV_KEY, KEY_WPS_BUTTON);
err = input_register_device(input);
- if (err)
+ if (err) {
+ input_free_device(input);
return err;
+ }
ar->wps.pbc = input;
return 0;
@@ -2044,6 +2046,13 @@ void carl9170_unregister(struct ar9170 *ar)
carl9170_debugfs_unregister(ar);
#endif /* CONFIG_CARL9170_DEBUGFS */
+#ifdef CONFIG_CARL9170_WPC
+ if (ar->wps.pbc) {
+ input_unregister_device(ar->wps.pbc);
+ ar->wps.pbc = NULL;
+ }
+#endif /* CONFIG_CARL9170_WPC */
+
carl9170_cancel_worker(ar);
cancel_work_sync(&ar->restart_work);
--
2.56.0.rc1.315.gc6ed9934b7-goog