Skip to content

Commit f8425c9

Browse files
balsiniMiklos Szeredi
authored andcommitted
fuse: 32-bit user space ioctl compat for fuse device
With a 64-bit kernel build the FUSE device cannot handle ioctl requests coming from 32-bit user space. This is due to the ioctl command translation that generates different command identifiers that thus cannot be used for direct comparisons without proper manipulation. Explicitly extract type and number from the ioctl command to enable 32-bit user space compatibility on 64-bit kernel builds. Signed-off-by: Alessio Balsini <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 3f9b9ef commit f8425c9

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

fs/fuse/dev.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,19 +2229,21 @@ static int fuse_device_clone(struct fuse_conn *fc, struct file *new)
22292229
static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
22302230
unsigned long arg)
22312231
{
2232-
int err = -ENOTTY;
2232+
int res;
2233+
int oldfd;
2234+
struct fuse_dev *fud = NULL;
22332235

2234-
if (cmd == FUSE_DEV_IOC_CLONE) {
2235-
int oldfd;
2236+
if (_IOC_TYPE(cmd) != FUSE_DEV_IOC_MAGIC)
2237+
return -ENOTTY;
22362238

2237-
err = -EFAULT;
2238-
if (!get_user(oldfd, (__u32 __user *) arg)) {
2239+
switch (_IOC_NR(cmd)) {
2240+
case _IOC_NR(FUSE_DEV_IOC_CLONE):
2241+
res = -EFAULT;
2242+
if (!get_user(oldfd, (__u32 __user *)arg)) {
22392243
struct file *old = fget(oldfd);
22402244

2241-
err = -EINVAL;
2245+
res = -EINVAL;
22422246
if (old) {
2243-
struct fuse_dev *fud = NULL;
2244-
22452247
/*
22462248
* Check against file->f_op because CUSE
22472249
* uses the same ioctl handler.
@@ -2252,14 +2254,18 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
22522254

22532255
if (fud) {
22542256
mutex_lock(&fuse_mutex);
2255-
err = fuse_device_clone(fud->fc, file);
2257+
res = fuse_device_clone(fud->fc, file);
22562258
mutex_unlock(&fuse_mutex);
22572259
}
22582260
fput(old);
22592261
}
22602262
}
2263+
break;
2264+
default:
2265+
res = -ENOTTY;
2266+
break;
22612267
}
2262-
return err;
2268+
return res;
22632269
}
22642270

22652271
const struct file_operations fuse_dev_operations = {

include/uapi/linux/fuse.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,8 @@ struct fuse_notify_retrieve_in {
903903
};
904904

905905
/* Device ioctls: */
906-
#define FUSE_DEV_IOC_CLONE _IOR(229, 0, uint32_t)
906+
#define FUSE_DEV_IOC_MAGIC 229
907+
#define FUSE_DEV_IOC_CLONE _IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t)
907908

908909
struct fuse_lseek_in {
909910
uint64_t fh;

0 commit comments

Comments
 (0)