aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2014-07-21 18:53:04 +0200
committerDan Pasanen <dan.pasanen@gmail.com>2015-10-28 21:00:18 -0500
commitf7f37f16aabe334c2422a933010ee4ff073938f7 (patch)
tree3f5cb4eb4298a8724267820d15d2fbb209c78be9
parent13a440a3b11b0cbb9e2d48dda2366bbecb06fb67 (diff)
downloadandroid_external_fuse-f7f37f16aabe334c2422a933010ee4ff073938f7.tar.gz
android_external_fuse-f7f37f16aabe334c2422a933010ee4ff073938f7.tar.bz2
android_external_fuse-f7f37f16aabe334c2422a933010ee4ff073938f7.zip
libfuse: highlevel API: fix directory file handle passed to ioctl() method
Reported by Eric Biggers Change-Id: I49119e982b11679edcafd9a87da69d965fd124a9
-rw-r--r--ChangeLog5
-rw-r--r--include/fuse.h3
-rw-r--r--lib/fuse.c10
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 <miklos@szeredi.hu>
+
+ * libfuse: highlevel API: fix directory file handle passed to
+ ioctl() method. Reported by Eric Biggers
+
2014-07-15 Miklos Szeredi <miklos@szeredi.hu>
* 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);