Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 06d2948e authored by Alessio Balsini's avatar Alessio Balsini Committed by Michael Bestas
Browse files

ANDROID: fuse/passthrough: API V2 with __u32 open argument

The initial FUSE passthrough interface has the issue of introducing an
ioctl which receives as a parameter a data structure containing a
pointer. What happens is that, depending on the architecture, the size
of this struct might change, and especially for 32-bit userspace running
on 64-bit kernel, the size mismatch results into different a single
ioctl the behavior of which depends on the data that is passed (e.g.,
with an enum). This is just a poor ioctl design as mentioned by Arnd
Bergmann [1].

Introduce the new FUSE_PASSTHROUGH_OPEN ioctl which only gets the fd of
the lower file system, which is a fixed-size __u32, dropping the
confusing fuse_passthrough_out data structure.

[1] https://lore.kernel.org/lkml/CAK8P3a2K2FzPvqBYL9W=Yut58SFXyetXwU4Fz50G5O3TsS0pPQ@mail.gmail.com/



Bug: 175195837
Signed-off-by: default avatarAlessio Balsini <balsini@google.com>
Change-Id: I486d71cbe20f3c0c87544fa75da4e2704fe57c7c
parent 4b9a79bd
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -2268,7 +2268,6 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
	int res;
	int oldfd;
	struct fuse_dev *fud = NULL;
	struct fuse_passthrough_out pto;

	if (_IOC_TYPE(cmd) != FUSE_DEV_IOC_MAGIC)
		return -EINVAL;
@@ -2301,13 +2300,11 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
		break;
	case _IOC_NR(FUSE_DEV_IOC_PASSTHROUGH_OPEN):
		res = -EFAULT;
		if (!copy_from_user(&pto,
				    (struct fuse_passthrough_out __user *)arg,
				    sizeof(pto))) {
		if (!get_user(oldfd, (__u32 __user *)arg)) {
			res = -EINVAL;
			fud = fuse_get_dev(file);
			if (fud)
				res = fuse_passthrough_open(fud, &pto);
				res = fuse_passthrough_open(fud, oldfd);
		}
		break;
	default:
+1 −2
Original line number Diff line number Diff line
@@ -1135,8 +1135,7 @@ u64 fuse_get_unique(struct fuse_iqueue *fiq);
void fuse_free_conn(struct fuse_conn *fc);

/* passthrough.c */
int fuse_passthrough_open(struct fuse_dev *fud,
			  struct fuse_passthrough_out *pto);
int fuse_passthrough_open(struct fuse_dev *fud, u32 lower_fd);
int fuse_passthrough_setup(struct fuse_conn *fc, struct fuse_file *ff,
			   struct fuse_open_out *openarg);
void fuse_passthrough_release(struct fuse_passthrough *passthrough);
+2 −7
Original line number Diff line number Diff line
@@ -191,8 +191,7 @@ ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma)
	return ret;
}

int fuse_passthrough_open(struct fuse_dev *fud,
			  struct fuse_passthrough_out *pto)
int fuse_passthrough_open(struct fuse_dev *fud, u32 lower_fd)
{
	int res;
	struct file *passthrough_filp;
@@ -204,11 +203,7 @@ int fuse_passthrough_open(struct fuse_dev *fud,
	if (!fc->passthrough)
		return -EPERM;

	/* This field is reserved for future implementation */
	if (pto->len != 0)
		return -EINVAL;

	passthrough_filp = fget(pto->fd);
	passthrough_filp = fget(lower_fd);
	if (!passthrough_filp) {
		pr_err("FUSE: invalid file descriptor for passthrough.\n");
		return -EBADF;
+3 −10
Original line number Diff line number Diff line
@@ -796,14 +796,6 @@ struct fuse_in_header {
	uint32_t	padding;
};

/* fuse_passthrough_out for passthrough V1 */
struct fuse_passthrough_out {
	uint32_t	fd;
	/* For future implementation */
	uint32_t	len;
	void		*vec;
};

struct fuse_out_header {
	uint32_t	len;
	int32_t		error;
@@ -881,8 +873,9 @@ struct fuse_notify_retrieve_in {
/* Device ioctls: */
#define FUSE_DEV_IOC_MAGIC		229
#define FUSE_DEV_IOC_CLONE		_IOR(FUSE_DEV_IOC_MAGIC, 0, uint32_t)
/* 127 is reserved for the V1 interface implementation in Android */
#define FUSE_DEV_IOC_PASSTHROUGH_OPEN	_IOW(FUSE_DEV_IOC_MAGIC, 127, struct fuse_passthrough_out)
/* 127 is reserved for the V1 interface implementation in Android (deprecated) */
/* 126 is reserved for the V2 interface implementation in Android */
#define FUSE_DEV_IOC_PASSTHROUGH_OPEN	_IOW(FUSE_DEV_IOC_MAGIC, 126, __u32)

struct fuse_lseek_in {
	uint64_t	fh;