[RFC PATCH] media: imon: stop receivers before shared input teardown
From: Wang Xiong
Date: Fri Oct 16 2026 - 00:19:29 EST
Both receive callbacks access the shared RC and panel input devices.
Interface-0 disconnect unregisters the RC device before stopping RX0,
while RX1 can still access the shared objects.
An archived KASAN report records a write in the interface-1 receive
callback after imon_disconnect() freed the RC allocation. The selected
frames include rc_g_keycode_from_table(), imon_incoming_packet() and
usb_rx_callback_intf1().
Stop RX0 and synchronously poison RX1 before unregistering either shared
input device. Keep RX1 poisoned so that a surviving interface cannot
resubmit receive transfers after shared input teardown.
Signed-off-by: Wang Xiong <20221010117@xxxxxxxxxxxxxxx>
---
Notes (mail-human-signoff-20261016):
This RFC addresses receive-callback ordering during input teardown. If
interface 0 is unbound while interface 1 remains bound, a later
interface-1 resume can return -EPERM while RX1 remains poisoned.
Independent unbind, suspend/resume and rebind behavior needs review.
These runtime paths have not been tested.
Selected fault frames from the archived report (excerpts):
BUG: KASAN: slab-use-after-free in _raw_spin_lock_irqsave
rc_g_keycode_from_table
imon_incoming_packet
usb_rx_callback_intf1
The precise runtime repair of the archived crash has not been verified.
No introducing commit is attributed by a Fixes tag in this RFC.
Build-tested with GCC 14.2.0 and binutils 2.44 on x86_64, against
base 03e2778d1f11de9260543f969e9e888a1c2bf830 (Linux 7.1.2).
The baseline and candidate bzImage/modules builds passed. The
candidate driver was enabled as a module in a minimal configuration.
The original crash configuration and runtime repair were not tested.
Related interface-ownership series, for review context:
https://lore.kernel.org/r/c922986ec1b360b47165a591b3a539abf3b8792e.1789460680.git.sean@xxxxxxxx
Please advise whether that series covers this receive/teardown
ordering or should be preferred over this RFC.
drivers/media/rc/imon.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 9bb27ba8240f831ff5de42b0df50642b283108f9..e27cec2c103fa919e01656f0ce200bd372c3b96c 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -2536,8 +2536,10 @@ static void imon_disconnect(struct usb_interface *interface)
if (ifnum == 0) {
ictx->dev_present_intf0 = false;
- rc_unregister_device(ictx->rdev);
usb_kill_urb(ictx->rx_urb_intf0);
+ /* Both interfaces use the RC device and panel input device. */
+ usb_poison_urb(ictx->rx_urb_intf1);
+ rc_unregister_device(ictx->rdev);
input_unregister_device(ictx->idev);
rc_free_device(ictx->rdev);
if (ictx->display_supported) {
base-commit: 03e2778d1f11de9260543f969e9e888a1c2bf830
--
2.47.3