[PATCH 1/2] fuse: fix device node leak in cuse_process_init_reply()
From: Alberto Ruiz via B4 Relay
Date: Wed Apr 08 2026 - 11:25:35 EST
From: Alberto Ruiz <aruiz@xxxxxxxxxx>
If device_add() succeeds during CUSE initialization but a subsequent
step (cdev_alloc() or cdev_add()) fails, the error path calls
put_device() without first calling device_del(). This leaks the
devtmpfs entry created by device_add(), leaving a stale /dev/<name>
node that persists until reboot.
Since the cuse_conn is never linked into cuse_conntbl on the failure
path, cuse_channel_release() sees cc->dev == NULL and skips
device_unregister(), so no other code path cleans up the node.
This has several consequences:
- The device name is permanently poisoned: any subsequent attempt to
create a CUSE device with the same name hits the stale sysfs entry,
device_add() fails, and the new device is aborted.
- The collision manifests as ENODEV returned to userspace with no
dmesg diagnostic, making it very difficult to debug.
- The failure is self-perpetuating: once a name is leaked, all future
attempts with that name fail identically.
Fix this by introducing an err_dev label that calls device_del() to
undo device_add() before falling through to err_unlock. The existing
err_unlock path from a device_add() failure correctly skips device_del()
since the device was never added.
Signed-off-by: Alberto Ruiz <aruiz@xxxxxxxxxx>
---
fs/fuse/cuse.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index dfcb98a654d83bb34460a6e8c9e4b196dfdfdfbe..df9d50a9c0fab269102ec0e4b2d459ca2a390c59 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -391,7 +391,7 @@ static void cuse_process_init_reply(struct fuse_mount *fm,
rc = -ENOMEM;
cdev = cdev_alloc();
if (!cdev)
- goto err_unlock;
+ goto err_dev;
cdev->owner = THIS_MODULE;
cdev->ops = &cuse_frontend_fops;
@@ -417,6 +417,8 @@ static void cuse_process_init_reply(struct fuse_mount *fm,
err_cdev:
cdev_del(cdev);
+err_dev:
+ device_del(dev);
err_unlock:
mutex_unlock(&cuse_lock);
put_device(dev);
--
2.52.0