[PATCH v1] uio: Fix stale info pointer in failed registration path

From: Yuho Choi

Date: Tue Jun 30 2026 - 15:27:30 EST


After device_add(), the UIO device is visible to userspace and /dev/uioX
can be opened. If a later setup step fails, __uio_register_device()
unwinds the device but leaves idev->info pointing at the caller-owned
struct uio_info.

That is unsafe when an opener races with the failed registration path.
The open file keeps a reference to the uio_device, while the caller sees
registration failure and may free its struct uio_info. Later file
operations can then follow idev->info and dereference freed memory.

Handle post-device_add() failures like unregister: remove UIO attributes
while the info pointer is still valid, then clear idev->info under
info_lock and wake existing waiters/async users before removing the
device and minor. This makes already-open file descriptors observe the
same "device gone" state as normal uio_unregister_device().

Fixes: a93e7b331568 ("uio: Prevent device destruction while fds are open")
Signed-off-by: Yuho Choi <dbgh9129@xxxxxxxxx>
---
drivers/uio/uio.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 1e4ade78ed84..e77d5e7d5f64 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -1057,6 +1057,11 @@ int __uio_register_device(struct module *owner,
err_request_irq:
uio_dev_del_attributes(idev);
err_uio_dev_add_attributes:
+ mutex_lock(&idev->info_lock);
+ idev->info = NULL;
+ mutex_unlock(&idev->info_lock);
+ wake_up_interruptible(&idev->wait);
+ kill_fasync(&idev->async_queue, SIGIO, POLL_HUP);
device_del(&idev->dev);
err_device_create:
uio_free_minor(idev->minor);
--
2.43.0