[PATCH v5 14/15] media: rc: Use after free in ir_raw_event_handle()

From: Sean Young

Date: Wed Jul 29 2026 - 12:11:45 EST


If rc_unregister_device() is called while IR is being processed, then
ir_raw_event_handle() could call wake_up_process(dev->raw->thread)
after kthread_stop(dev->raw->thread). Avoid use after free by using
get_task_struct().

Fixes: dccc0c3ddf8f ("media: rc: fix race between unregister and urb/irq callbacks")
Signed-off-by: Sean Young <sean@xxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
drivers/media/rc/rc-ir-raw.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index 46c50f423798..86de1b26731d 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -630,8 +630,13 @@ int ir_raw_event_register(struct rc_dev *dev)

void ir_raw_event_free(struct rc_dev *dev)
{
- kfree(dev->raw);
- dev->raw = NULL;
+ if (dev->raw) {
+ timer_delete_sync(&dev->raw->edge_handle);
+ if (dev->raw->thread)
+ put_task_struct(dev->raw->thread);
+ kfree(dev->raw);
+ dev->raw = NULL;
+ }
}

void ir_raw_event_unregister(struct rc_dev *dev)
@@ -641,6 +646,13 @@ void ir_raw_event_unregister(struct rc_dev *dev)
if (!dev || !dev->raw)
return;

+ /*
+ * After ir_raw_event_unregister() is called, an sync
+ * call to ir_raw_event_handle() can still arrive. This function
+ * may call wake_up_process(dev->raw->thread). Ensure this memory
+ * is not freed by kthread_stop().
+ */
+ get_task_struct(dev->raw->thread);
kthread_stop(dev->raw->thread);
timer_delete_sync(&dev->raw->edge_handle);

--
2.55.0