^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * CUSE: Character device in Userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2008-2009 SUSE Linux Products GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2008-2009 Tejun Heo <tj@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * CUSE enables character devices to be implemented from userland much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * like FUSE allows filesystems. On initialization /dev/cuse is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * created. By opening the file and replying to the CUSE_INIT request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * userland CUSE server can create a character device. After that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * operation is very similar to FUSE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * A CUSE instance involves the following objects.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * cuse_conn : contains fuse_conn and serves as bonding structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * channel : file handle connected to the userland CUSE server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * cdev : the implemented character device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * dev : generic device for cdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Note that 'channel' is what 'dev' is in FUSE. As CUSE deals with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * devices, it's called 'channel' to reduce confusion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * channel determines when the character device dies. When channel is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * closed, everything begins to destruct. The cuse_conn is taken off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * the lookup table preventing further access from cdev, cdev and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * generic device are removed and the base reference of cuse_conn is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * put.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * On each open, the matching cuse_conn is looked up and if found an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * additional reference is taken which is released when the file is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define pr_fmt(fmt) "CUSE: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/fuse.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/kdev_t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/user_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "fuse_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define CUSE_CONNTBL_LEN 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct cuse_conn {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct list_head list; /* linked on cuse_conntbl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct fuse_mount fm; /* Dummy mount referencing fc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct fuse_conn fc; /* fuse connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct cdev *cdev; /* associated character device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct device *dev; /* device representing @cdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* init parameters, set once during initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) bool unrestricted_ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static DEFINE_MUTEX(cuse_lock); /* protects registration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static struct list_head cuse_conntbl[CUSE_CONNTBL_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct class *cuse_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static struct cuse_conn *fc_to_cc(struct fuse_conn *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return container_of(fc, struct cuse_conn, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static struct list_head *cuse_conntbl_head(dev_t devt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return &cuse_conntbl[(MAJOR(devt) + MINOR(devt)) % CUSE_CONNTBL_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * CUSE frontend operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * These are file operations for the character device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * On open, CUSE opens a file from the FUSE mnt and stores it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * private_data of the open file. All other ops call FUSE ops on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * FUSE file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static ssize_t cuse_read_iter(struct kiocb *kiocb, struct iov_iter *to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) loff_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return fuse_direct_io(&io, to, &pos, FUSE_DIO_CUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static ssize_t cuse_write_iter(struct kiocb *kiocb, struct iov_iter *from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) loff_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * No locking or generic_write_checks(), the server is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * responsible for locking and sanity checks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return fuse_direct_io(&io, from, &pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) FUSE_DIO_WRITE | FUSE_DIO_CUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int cuse_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) dev_t devt = inode->i_cdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct cuse_conn *cc = NULL, *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* look up and get the connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mutex_lock(&cuse_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) list_for_each_entry(pos, cuse_conntbl_head(devt), list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (pos->dev->devt == devt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) fuse_conn_get(&pos->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) cc = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mutex_unlock(&cuse_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* dead? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (!cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * Generic permission check is already done against the chrdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * file, proceed to open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) rc = fuse_do_open(&cc->fm, 0, file, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) fuse_conn_put(&cc->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int cuse_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct fuse_file *ff = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct fuse_mount *fm = ff->fm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) fuse_sync_release(NULL, ff, file->f_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) fuse_conn_put(fm->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static long cuse_file_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct fuse_file *ff = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct cuse_conn *cc = fc_to_cc(ff->fm->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (cc->unrestricted_ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) flags |= FUSE_IOCTL_UNRESTRICTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return fuse_do_ioctl(file, cmd, arg, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static long cuse_file_compat_ioctl(struct file *file, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct fuse_file *ff = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct cuse_conn *cc = fc_to_cc(ff->fm->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) unsigned int flags = FUSE_IOCTL_COMPAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (cc->unrestricted_ioctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) flags |= FUSE_IOCTL_UNRESTRICTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return fuse_do_ioctl(file, cmd, arg, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static const struct file_operations cuse_frontend_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) .read_iter = cuse_read_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) .write_iter = cuse_write_iter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .open = cuse_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .release = cuse_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .unlocked_ioctl = cuse_file_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .compat_ioctl = cuse_file_compat_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .poll = fuse_file_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * CUSE channel initialization and destruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct cuse_devinfo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * cuse_parse_one - parse one key=value pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * @pp: i/o parameter for the current position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * @end: points to one past the end of the packed string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @keyp: out parameter for key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * @valp: out parameter for value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * *@pp points to packed strings - "key0=val0\0key1=val1\0" which ends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * at @end - 1. This function parses one pair and set *@keyp to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * start of the key and *@valp to the start of the value. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * the original string is modified such that the key string is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * terminated with '\0'. *@pp is updated to point to the next string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * 1 on successful parse, 0 on EOF, -errno on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) char *p = *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) char *key, *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) while (p < end && *p == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (p == end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (end[-1] != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pr_err("info not properly terminated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) key = val = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) p += strlen(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (valp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) strsep(&val, "=");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) val = key + strlen(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) key = strstrip(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) val = strstrip(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) key = strstrip(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!strlen(key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) pr_err("zero length info key specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *pp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *keyp = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (valp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *valp = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * cuse_parse_dev_info - parse device info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @p: device info string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * @len: length of device info string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * @devinfo: out parameter for parsed device info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Parse @p to extract device info and store it into @devinfo. String
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * pointed to by @p is modified by parsing and @devinfo points into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * them, so @p shouldn't be freed while @devinfo is in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * 0 on success, -errno on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) char *end = p + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) char *key, *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) rc = cuse_parse_one(&p, end, &key, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (!rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (strcmp(key, "DEVNAME") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) devinfo->name = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pr_warn("unknown device info \"%s\"\n", key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (!devinfo->name || !strlen(devinfo->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pr_err("DEVNAME unspecified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void cuse_gendev_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct cuse_init_args {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct fuse_args_pages ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct cuse_init_in in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct cuse_init_out out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct fuse_page_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * cuse_process_init_reply - finish initializing CUSE channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * This function creates the character device and sets up all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * required data structures for it. Please read the comment at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * top of this file for high level overview.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void cuse_process_init_reply(struct fuse_mount *fm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct fuse_args *args, int error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct fuse_conn *fc = fm->fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct cuse_init_args *ia = container_of(args, typeof(*ia), ap.args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct fuse_args_pages *ap = &ia->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct cuse_conn *cc = fc_to_cc(fc), *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct cuse_init_out *arg = &ia->out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct page *page = ap->pages[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct cuse_devinfo devinfo = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct cdev *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) dev_t devt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int rc, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (error || arg->major != FUSE_KERNEL_VERSION || arg->minor < 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) fc->minor = arg->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) fc->max_read = max_t(unsigned, arg->max_read, 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) fc->max_write = max_t(unsigned, arg->max_write, 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* parse init reply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) cc->unrestricted_ioctl = arg->flags & CUSE_UNRESTRICTED_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) rc = cuse_parse_devinfo(page_address(page), ap->args.out_args[1].size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) &devinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* determine and reserve devt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) devt = MKDEV(arg->dev_major, arg->dev_minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (!MAJOR(devt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) rc = alloc_chrdev_region(&devt, MINOR(devt), 1, devinfo.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) rc = register_chrdev_region(devt, 1, devinfo.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) pr_err("failed to register chrdev region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* devt determined, create device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) goto err_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) device_initialize(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dev_set_uevent_suppress(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) dev->class = cuse_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) dev->devt = devt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) dev->release = cuse_gendev_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev_set_drvdata(dev, cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) dev_set_name(dev, "%s", devinfo.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) mutex_lock(&cuse_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* make sure the device-name is unique */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) for (i = 0; i < CUSE_CONNTBL_LEN; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) list_for_each_entry(pos, &cuse_conntbl[i], list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (!strcmp(dev_name(pos->dev), dev_name(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) rc = device_add(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* register cdev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) cdev = cdev_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) cdev->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) cdev->ops = &cuse_frontend_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) rc = cdev_add(cdev, devt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) goto err_cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) cc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) cc->cdev = cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* make the device available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) list_add(&cc->list, cuse_conntbl_head(devt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mutex_unlock(&cuse_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* announce device availability */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) dev_set_uevent_suppress(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) kobject_uevent(&dev->kobj, KOBJ_ADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) kfree(ia);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) __free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) err_cdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) cdev_del(cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) mutex_unlock(&cuse_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) err_region:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) unregister_chrdev_region(devt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) fuse_abort_conn(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int cuse_send_init(struct cuse_conn *cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct fuse_mount *fm = &cc->fm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct cuse_init_args *ia;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct fuse_args_pages *ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) BUILD_BUG_ON(CUSE_INIT_INFO_MAX > PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) page = alloc_page(GFP_KERNEL | __GFP_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ia = kzalloc(sizeof(*ia), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (!ia)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) goto err_free_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ap = &ia->ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ia->in.major = FUSE_KERNEL_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ia->in.minor = FUSE_KERNEL_MINOR_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ia->in.flags |= CUSE_UNRESTRICTED_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ap->args.opcode = CUSE_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ap->args.in_numargs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ap->args.in_args[0].size = sizeof(ia->in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ap->args.in_args[0].value = &ia->in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ap->args.out_numargs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ap->args.out_args[0].size = sizeof(ia->out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ap->args.out_args[0].value = &ia->out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ap->args.out_args[1].size = CUSE_INIT_INFO_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ap->args.out_argvar = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ap->args.out_pages = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ap->num_pages = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ap->pages = &ia->page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ap->descs = &ia->desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ia->page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ia->desc.length = ap->args.out_args[1].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ap->args.end = cuse_process_init_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) rc = fuse_simple_background(fm, &ap->args, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) kfree(ia);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) err_free_page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) __free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static void cuse_fc_release(struct fuse_conn *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct cuse_conn *cc = fc_to_cc(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) kfree_rcu(cc, fc.rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * cuse_channel_open - open method for /dev/cuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * @inode: inode for /dev/cuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * @file: file struct being opened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * Userland CUSE server can create a CUSE device by opening /dev/cuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * and replying to the initialization request kernel sends. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * function is responsible for handling CUSE device initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * Because the fd opened by this function is used during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * initialization, this function only creates cuse_conn and sends
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * init. The rest is delegated to a kthread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * 0 on success, -errno on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static int cuse_channel_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct fuse_dev *fud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct cuse_conn *cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* set up cuse_conn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) cc = kzalloc(sizeof(*cc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (!cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * Limit the cuse channel to requests that can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * be represented in file->f_cred->user_ns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) fuse_conn_init(&cc->fc, &cc->fm, file->f_cred->user_ns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) &fuse_dev_fiq_ops, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) fud = fuse_dev_alloc_install(&cc->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (!fud) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) kfree(cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) INIT_LIST_HEAD(&cc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) cc->fc.release = cuse_fc_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) cc->fc.initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) rc = cuse_send_init(cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) fuse_dev_free(fud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) fuse_conn_put(&cc->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) file->private_data = fud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * cuse_channel_release - release method for /dev/cuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * @inode: inode for /dev/cuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * @file: file struct being closed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * Disconnect the channel, deregister CUSE device and initiate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * destruction by putting the default reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * RETURNS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * 0 on success, -errno on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static int cuse_channel_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct fuse_dev *fud = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct cuse_conn *cc = fc_to_cc(fud->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* remove from the conntbl, no more access from this point on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) mutex_lock(&cuse_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) list_del_init(&cc->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) mutex_unlock(&cuse_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* remove device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (cc->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) device_unregister(cc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (cc->cdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) unregister_chrdev_region(cc->cdev->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) cdev_del(cc->cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* Base reference is now owned by "fud" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) fuse_conn_put(&cc->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) rc = fuse_dev_release(inode, file); /* puts the base reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static struct file_operations cuse_channel_fops; /* initialized during init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * Misc stuff and module initializatiion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * CUSE exports the same set of attributes to sysfs as fusectl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static ssize_t cuse_class_waiting_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct cuse_conn *cc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static DEVICE_ATTR(waiting, 0400, cuse_class_waiting_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static ssize_t cuse_class_abort_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct cuse_conn *cc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) fuse_abort_conn(&cc->fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static DEVICE_ATTR(abort, 0200, NULL, cuse_class_abort_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static struct attribute *cuse_class_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) &dev_attr_waiting.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) &dev_attr_abort.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ATTRIBUTE_GROUPS(cuse_class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static struct miscdevice cuse_miscdev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .minor = CUSE_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .name = "cuse",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) .fops = &cuse_channel_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) MODULE_ALIAS_MISCDEV(CUSE_MINOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) MODULE_ALIAS("devname:cuse");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static int __init cuse_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /* init conntbl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) for (i = 0; i < CUSE_CONNTBL_LEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) INIT_LIST_HEAD(&cuse_conntbl[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* inherit and extend fuse_dev_operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) cuse_channel_fops = fuse_dev_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) cuse_channel_fops.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) cuse_channel_fops.open = cuse_channel_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) cuse_channel_fops.release = cuse_channel_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* CUSE is not prepared for FUSE_DEV_IOC_CLONE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) cuse_channel_fops.unlocked_ioctl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) cuse_class = class_create(THIS_MODULE, "cuse");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (IS_ERR(cuse_class))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return PTR_ERR(cuse_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) cuse_class->dev_groups = cuse_class_dev_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) rc = misc_register(&cuse_miscdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) class_destroy(cuse_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static void __exit cuse_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) misc_deregister(&cuse_miscdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) class_destroy(cuse_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) module_init(cuse_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) module_exit(cuse_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) MODULE_AUTHOR("Tejun Heo <tj@kernel.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) MODULE_DESCRIPTION("Character device in Userspace");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) MODULE_LICENSE("GPL");