Skip to content

Commit

Permalink
fuse: Add ioctl flag for x32 compat ioctl
Browse files Browse the repository at this point in the history
Currently, a CUSE server running on a 64-bit kernel can tell when an ioctl
request comes from a process running a 32-bit ABI, but cannot tell whether
the requesting process is using legacy IA32 emulation or x32 ABI.  In
particular, the server does not know the size of the client process's
`time_t` type.

For 64-bit kernels, the `FUSE_IOCTL_COMPAT` and `FUSE_IOCTL_32BIT` flags
are currently set in the ioctl input request (`struct fuse_ioctl_in` member
`flags`) for a 32-bit requesting process.  This patch defines a new flag
`FUSE_IOCTL_COMPAT_X32` and sets it if the 32-bit requesting process is
using the x32 ABI.  This allows the server process to distinguish between
requests coming from client processes using IA32 emulation or the x32 ABI
and so infer the size of the client process's `time_t` type and any other
IA32/x32 differences.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
  • Loading branch information
Ian Abbott authored and Miklos Szeredi committed Apr 24, 2019
1 parent 29cc02d commit 6407f44
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
7 changes: 6 additions & 1 deletion fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2578,8 +2578,13 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
#if BITS_PER_LONG == 32
inarg.flags |= FUSE_IOCTL_32BIT;
#else
if (flags & FUSE_IOCTL_COMPAT)
if (flags & FUSE_IOCTL_COMPAT) {
inarg.flags |= FUSE_IOCTL_32BIT;
#ifdef CONFIG_X86_X32
if (in_x32_syscall())
inarg.flags |= FUSE_IOCTL_COMPAT_X32;
#endif
}
#endif

/* assume all the iovs returned by client always fits in a page */
Expand Down
3 changes: 3 additions & 0 deletions include/uapi/linux/fuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
*
* 7.30
* - add FUSE_EXPLICIT_INVAL_DATA
* - add FUSE_IOCTL_COMPAT_X32
*/

#ifndef _LINUX_FUSE_H
Expand Down Expand Up @@ -343,6 +344,7 @@ struct fuse_file_lock {
* FUSE_IOCTL_RETRY: retry with new iovecs
* FUSE_IOCTL_32BIT: 32bit ioctl
* FUSE_IOCTL_DIR: is a directory
* FUSE_IOCTL_COMPAT_X32: x32 compat ioctl on 64bit machine (64bit time_t)
*
* FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
*/
Expand All @@ -351,6 +353,7 @@ struct fuse_file_lock {
#define FUSE_IOCTL_RETRY (1 << 2)
#define FUSE_IOCTL_32BIT (1 << 3)
#define FUSE_IOCTL_DIR (1 << 4)
#define FUSE_IOCTL_COMPAT_X32 (1 << 5)

#define FUSE_IOCTL_MAX_IOV 256

Expand Down

0 comments on commit 6407f44

Please sign in to comment.