diff options
author | Csaba Henk <csaba@redhat.com> | 2020-10-15 23:31:08 +0200 |
---|---|---|
committer | Xavi Hernandez <xhernandez@users.noreply.github.com> | 2020-12-15 12:01:36 +0100 |
commit | 68987b050cc1a0fcf088ab981acbe6a2d1b22972 (patch) | |
tree | eebcc68af760d1b9576f1af3821f1f4f875d8ea5 | |
parent | 9c2bd7cbf6c00604d12a42de463e09739f6a84bc (diff) | |
download | glusterfs-68987b050cc1a0fcf088ab981acbe6a2d1b22972.tar.gz glusterfs-68987b050cc1a0fcf088ab981acbe6a2d1b22972.tar.xz glusterfs-68987b050cc1a0fcf088ab981acbe6a2d1b22972.zip |
fuse: sanitize FUSE_OP_HIGH
The idea behind FUSE_OP_HIGH was that it should be
the upper limit for the opcodes we can ever get from kernel
(maximum opcode that can occur plus one).
The problem with this idea is that this depends on the FUSE
protocol version; and since the fuse proto header does not export
this value, it has to be retroactively defined considering
the particular opcode values in the protocol header. That is, not
just the value, but the definition itself depends on the FUSE
protocol version. So we ended up maintaining -- or indeed, not
even maintaining, just living with -- a mess of conditional
defines for FUSE_OP_HIGH.
Now we change the meaning of it: FUSE_OP_HIGH will simply be
upper limit of the opcodes for which we define a handler
(the highest such opcode plus one, which is the same as the
size of the fuse optable).
The practical implication of this change is as follows.
Potentially there is a gap between the new and the old value
of FUSE_OP_HIGH: those opcodes which might occur in requests
but are higher than any opcode we handle. With the old definition
of FUSE_OP_HIGH we could statically dispatch these opcodes to
fuse_enosys() (a function that sends a FUSE response with error
ENOSYS).
With the new definition we don't know the upper limit of this gap,
so we need to dispatch the opcodes of the gap to fuse_enosys()
dynamically (perform a runtime check if the opcode is
greater-or-equal than the new FUSE_OP_HIGH, and if yes, then call
fuse_enosys()).
Change-Id: I8cd26ead538de8ce36c91feaf938e4c5dc59c88c
Updates: #1000
Signed-off-by: Csaba Henk <csaba@redhat.com>
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 135 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.h | 30 |
2 files changed, 70 insertions, 95 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 042f1c6c4c..d1b8795c8b 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -5959,6 +5959,72 @@ fuse_get_mount_status(xlator_t *this) return kid_status; } +static fuse_handler_t *fuse_std_ops[] = { + [FUSE_LOOKUP] = fuse_lookup, + [FUSE_FORGET] = fuse_forget, + [FUSE_GETATTR] = fuse_getattr, + [FUSE_SETATTR] = fuse_setattr, + [FUSE_READLINK] = fuse_readlink, + [FUSE_SYMLINK] = fuse_symlink, + [FUSE_MKNOD] = fuse_mknod, + [FUSE_MKDIR] = fuse_mkdir, + [FUSE_UNLINK] = fuse_unlink, + [FUSE_RMDIR] = fuse_rmdir, + [FUSE_RENAME] = fuse_rename, + [FUSE_LINK] = fuse_link, + [FUSE_OPEN] = fuse_open, + [FUSE_READ] = fuse_readv, + [FUSE_WRITE] = fuse_write, + [FUSE_STATFS] = fuse_statfs, + [FUSE_RELEASE] = fuse_release, + [FUSE_FSYNC] = fuse_fsync, + [FUSE_SETXATTR] = fuse_setxattr, + [FUSE_GETXATTR] = fuse_getxattr, + [FUSE_LISTXATTR] = fuse_listxattr, + [FUSE_REMOVEXATTR] = fuse_removexattr, + [FUSE_FLUSH] = fuse_flush, + [FUSE_INIT] = fuse_init, + [FUSE_OPENDIR] = fuse_opendir, + [FUSE_READDIR] = fuse_readdir, + [FUSE_RELEASEDIR] = fuse_releasedir, + [FUSE_FSYNCDIR] = fuse_fsyncdir, + [FUSE_GETLK] = fuse_getlk, + [FUSE_SETLK] = fuse_setlk, + [FUSE_SETLKW] = fuse_setlk, + [FUSE_ACCESS] = fuse_access, + [FUSE_CREATE] = fuse_create, + [FUSE_INTERRUPT] = fuse_interrupt, + /* [FUSE_BMAP] */ + [FUSE_DESTROY] = fuse_destroy, +/* [FUSE_IOCTL] */ +/* [FUSE_POLL] */ +/* [FUSE_NOTIFY_REPLY] */ + +#if FUSE_KERNEL_MINOR_VERSION >= 16 + [FUSE_BATCH_FORGET] = fuse_batch_forget, +#endif + +#if FUSE_KERNEL_MINOR_VERSION >= 19 +#ifdef FALLOC_FL_KEEP_SIZE + [FUSE_FALLOCATE] = fuse_fallocate, +#endif /* FALLOC_FL_KEEP_SIZE */ +#endif + +#if FUSE_KERNEL_MINOR_VERSION >= 21 + [FUSE_READDIRPLUS] = fuse_readdirp, +#endif + +#if FUSE_KERNEL_MINOR_VERSION >= 24 && HAVE_SEEK_HOLE + [FUSE_LSEEK] = fuse_lseek, +#endif + +#if FUSE_KERNEL_MINOR_VERSION >= 28 + [FUSE_COPY_FILE_RANGE] = fuse_copy_file_range, +#endif +}; + +#define FUSE_OP_HIGH (sizeof(fuse_std_ops) / sizeof(*fuse_std_ops)) + static void fuse_dispatch(xlator_t *xl, gf_async_t *async) { @@ -5972,7 +6038,10 @@ fuse_dispatch(xlator_t *xl, gf_async_t *async) finh = fasync->finh; iobuf = fasync->iobuf; - priv->fuse_ops[finh->opcode](xl, finh, fasync->msg, iobuf); + if (finh->opcode >= FUSE_OP_HIGH) + fuse_enosys(xl, finh, NULL, NULL); + else + priv->fuse_ops[finh->opcode](xl, finh, fasync->msg, iobuf); iobuf_unref(iobuf); } @@ -6536,70 +6605,6 @@ mem_acct_init(xlator_t *this) return ret; } -static fuse_handler_t *fuse_std_ops[FUSE_OP_HIGH] = { - [FUSE_LOOKUP] = fuse_lookup, - [FUSE_FORGET] = fuse_forget, - [FUSE_GETATTR] = fuse_getattr, - [FUSE_SETATTR] = fuse_setattr, - [FUSE_READLINK] = fuse_readlink, - [FUSE_SYMLINK] = fuse_symlink, - [FUSE_MKNOD] = fuse_mknod, - [FUSE_MKDIR] = fuse_mkdir, - [FUSE_UNLINK] = fuse_unlink, - [FUSE_RMDIR] = fuse_rmdir, - [FUSE_RENAME] = fuse_rename, - [FUSE_LINK] = fuse_link, - [FUSE_OPEN] = fuse_open, - [FUSE_READ] = fuse_readv, - [FUSE_WRITE] = fuse_write, - [FUSE_STATFS] = fuse_statfs, - [FUSE_RELEASE] = fuse_release, - [FUSE_FSYNC] = fuse_fsync, - [FUSE_SETXATTR] = fuse_setxattr, - [FUSE_GETXATTR] = fuse_getxattr, - [FUSE_LISTXATTR] = fuse_listxattr, - [FUSE_REMOVEXATTR] = fuse_removexattr, - [FUSE_FLUSH] = fuse_flush, - [FUSE_INIT] = fuse_init, - [FUSE_OPENDIR] = fuse_opendir, - [FUSE_READDIR] = fuse_readdir, - [FUSE_RELEASEDIR] = fuse_releasedir, - [FUSE_FSYNCDIR] = fuse_fsyncdir, - [FUSE_GETLK] = fuse_getlk, - [FUSE_SETLK] = fuse_setlk, - [FUSE_SETLKW] = fuse_setlk, - [FUSE_ACCESS] = fuse_access, - [FUSE_CREATE] = fuse_create, - [FUSE_INTERRUPT] = fuse_interrupt, - /* [FUSE_BMAP] */ - [FUSE_DESTROY] = fuse_destroy, -/* [FUSE_IOCTL] */ -/* [FUSE_POLL] */ -/* [FUSE_NOTIFY_REPLY] */ - -#if FUSE_KERNEL_MINOR_VERSION >= 16 - [FUSE_BATCH_FORGET] = fuse_batch_forget, -#endif - -#if FUSE_KERNEL_MINOR_VERSION >= 19 -#ifdef FALLOC_FL_KEEP_SIZE - [FUSE_FALLOCATE] = fuse_fallocate, -#endif /* FALLOC_FL_KEEP_SIZE */ -#endif - -#if FUSE_KERNEL_MINOR_VERSION >= 21 - [FUSE_READDIRPLUS] = fuse_readdirp, -#endif - -#if FUSE_KERNEL_MINOR_VERSION >= 24 && HAVE_SEEK_HOLE - [FUSE_LSEEK] = fuse_lseek, -#endif - -#if FUSE_KERNEL_MINOR_VERSION >= 28 - [FUSE_COPY_FILE_RANGE] = fuse_copy_file_range, -#endif -}; - static fuse_handler_t *fuse_dump_ops[FUSE_OP_HIGH]; static void diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h index 4cb94c23ca..f40b79b9d4 100644 --- a/xlators/mount/fuse/src/fuse-bridge.h +++ b/xlators/mount/fuse/src/fuse-bridge.h @@ -40,36 +40,6 @@ #include <glusterfs/syncop.h> #include <glusterfs/gidcache.h> -#if defined(GF_LINUX_HOST_OS) || defined(__FreeBSD__) || defined(__NetBSD__) - -/* - * TODO: - * So, with the addition of copy_file_range support, it might - * require a bump up of fuse kernel minor version (like it was - * done when support for lseek fop was added. But, as of now, - * the copy_file_range support has just landed in upstream - * kernel fuse module. So, until, there is a release of that - * fuse as part of a kernel, the FUSE_KERNEL_MINOR_VERSION - * from fuse_kernel.h in the contrib might not be changed. - * If so, then the highest op available should be based on - * the current minor version (which is 24). So, selectively - * determine. When, the minor version is changed to 28 in - * fuse_kernel.h from contrib (because in upstream linux - * kernel source tree, the kernel minor version which - * contains support for copy_file_range is 28), then remove - * the reference to FUSE_LSEEK below and just determine - * FUSE_OP_HIGH based on copy_file_range. - */ -#if FUSE_KERNEL_MINOR_VERSION >= 28 -#define FUSE_OP_HIGH (FUSE_COPY_FILE_RANGE + 1) -#else -#define FUSE_OP_HIGH (FUSE_LSEEK + 1) -#endif - -#endif -#ifdef GF_DARWIN_HOST_OS -#define FUSE_OP_HIGH (FUSE_DESTROY + 1) -#endif #define GLUSTERFS_XATTR_LEN_MAX 65536 #define MAX_FUSE_PROC_DELAY 1 |