Re: [PATCH v2] media: rc: fix use-after-free of rc_map.name on register error path

From: YuanZhe Liu

Date: Fri Oct 30 2026 - 09:06:27 EST


Hi Sean,

You are right, and thanks - that is a good point. Once rc_dev_uevent()
returns -ENODEV, dev_uevent() fails and kobject_uevent_env() bails out,
so the KOBJ_REMOVE event is never sent at all. udev has seen the
KOBJ_ADD, so suppressing the remove leaves it with a stale device. That
is the wrong direction.

The strings themselves are not the problem at the point the remove
uevent is generated: rc_map.name, driver_name and device_name are all
still valid until the driver frees the rc_dev after rc_register_device()
returns, which is well after device_del(). What we need is that nothing
is freed before the uevent is sent, not that the uevent is suppressed.

So the error path should keep the device registered until device_del()
has sent the remove uevent: at out_rx only unregister the input device
(it is a child of dev->dev), keep the keymap for the uevent, and move
both the clearing of registered and the freeing of the keymap after
device_del(). device_del() drains the sysfs readers, so rc_dev_uevent()
cannot run afterwards and rc_map.name can be freed at that point.

Something like this against next-20261026:

out_rx:
- rc_free_rx_device(dev);
+ /* Keep the keymap until the remove uevent has been sent. */
+ if (dev->input_dev) {
+ input_unregister_device(dev->input_dev);
+ dev->input_dev = NULL;
+ }
out_lirc:
- scoped_guard(mutex, &dev->lock)
- dev->registered = false;
-
lirc_unregister(dev);
device_del(&dev->dev);
- /* registered already cleared above */
+
+ /*
+ * The remove uevent has been sent and the sysfs readers have
+ * been drained; lirc file descriptors that are still open must
+ * not reach the driver any more.
+ */
+ scoped_guard(mutex, &dev->lock)
+ dev->registered = false;
goto out_free_table;

out_free_table already frees the keymap after device_del(), so the
out_rx path gets the deferred free without a new label. rc_dev_uevent()
keeps its registered check: it is still what keeps open lirc descriptors
away from the driver, and it now runs only after the uevent has been
delivered.

The same ordering exists in rc_unregister_device() since 4f0835d6677d:
it clears registered and frees the input device and the keymap before
device_del(), so the remove uevent is suppressed there as well. I am
happy to send the error path patch only, or to extend it to
rc_unregister_device() as well - let me know which you prefer, and I
will rebase it on linux-next.

If you fold this into your series, a Reported-by: YuanZhe Liu
<25031212351@xxxxxxxxxxxxxxxxx> for the analysis would be appreciated.

Thanks,
YuanZhe