fuse: prevent possible fuse_pollhandle leak

Documentation for poll() callback says that:
> The callee is responsible for destroying ph with
> fuse_pollhandle_destroy() when no longer in use.

In fuse_lib_poll() ((struct fuse_lowlevel_ops*)->poll) we need to be more
careful:

1. If get_path_nullok() fails, we need to free fuse_pollhandle
2. If we passed execution down to fuse_fs_poll(), then
it must release fuse_pollhandle resources when no
(struct fuse_operations*)->poll provided by the filesystem driver.

Found this by myself while reading the code as a part of [1] review.

This is not critical at all, because once we return ENOSYS once,
kernel never sends FUSE_POLL again. So memleak is unnoticable in practice.
Alternatively, we can leak if get_path_nullok() fails all the time, but
then we are in a much more serious troubles...

Link: https://github.com/lxc/lxcfs/pull/726 [1]
Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io>
This commit is contained in:
Alexander Mikhalitsyn
2026-05-12 15:28:30 +02:00
committed by Bernd Schubert
parent 6b3123617b
commit baebe3cde9
+7 -1
View File
@@ -2271,8 +2271,12 @@ int fuse_fs_poll(struct fuse_fs *fs, const char *path,
int res;
fuse_get_context()->private_data = fs->user_data;
if (!fs->op.poll)
if (!fs->op.poll) {
fuse_pollhandle_destroy(ph);
return -ENOSYS;
}
if (fs->debug)
fuse_log(FUSE_LOG_DEBUG, "poll[%llu] ph: %p, events 0x%x\n",
(unsigned long long) fi->fh, ph,
@@ -4348,6 +4352,8 @@ static void fuse_lib_poll(fuse_req_t req, fuse_ino_t ino,
err = fuse_fs_poll(f->fs, path, fi, ph, &revents);
fuse_finish_interrupt(f, req, &d);
free_path(f, ino, path);
} else {
fuse_pollhandle_destroy(ph);
}
if (!err)
fuse_reply_poll(req, revents);