From f7f37f16aabe334c2422a933010ee4ff073938f7 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 21 Jul 2014 18:53:04 +0200 Subject: libfuse: highlevel API: fix directory file handle passed to ioctl() method Reported by Eric Biggers Change-Id: I49119e982b11679edcafd9a87da69d965fd124a9 --- ChangeLog | 5 +++++ include/fuse.h | 3 +++ lib/fuse.c | 10 ++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7618b14..b8ccda9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2014-07-21 Miklos Szeredi + + * libfuse: highlevel API: fix directory file handle passed to + ioctl() method. Reported by Eric Biggers + 2014-07-15 Miklos Szeredi * libfuse: document deadlock avoidance for diff --git a/include/fuse.h b/include/fuse.h index 5aba010..b82325e 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -503,6 +503,9 @@ struct fuse_operations { * _IOC_READ in area and if both are set in/out area. In all * non-NULL cases, the area is of _IOC_SIZE(cmd) bytes. * + * If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a + * directory file handle. + * * Introduced in version 2.8 */ int (*ioctl) (const char *, int cmd, void *arg, diff --git a/lib/fuse.c b/lib/fuse.c index d214b36..2c1aa17 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -4008,12 +4008,13 @@ static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize, } static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, - struct fuse_file_info *fi, unsigned int flags, + struct fuse_file_info *llfi, unsigned int flags, const void *in_buf, size_t in_bufsz, size_t out_bufsz) { struct fuse *f = req_fuse_prepare(req); struct fuse_intr_data d; + struct fuse_file_info fi; char *path, *out_buf = NULL; int err; @@ -4021,6 +4022,11 @@ static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, if (flags & FUSE_IOCTL_UNRESTRICTED) goto err; + if (flags & FUSE_IOCTL_DIR) + get_dirhandle(llfi, &fi); + else + fi = *llfi; + if (out_bufsz) { err = -ENOMEM; out_buf = malloc(out_bufsz); @@ -4038,7 +4044,7 @@ static void fuse_lib_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, fuse_prepare_interrupt(f, req, &d); - err = fuse_fs_ioctl(f->fs, path, cmd, arg, fi, flags, + err = fuse_fs_ioctl(f->fs, path, cmd, arg, &fi, flags, out_buf ?: (void *)in_buf); fuse_finish_interrupt(f, req, &d); -- cgit v1.2.3