linux/drivers/char/raw.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/drivers/char/raw.c
   4 *
   5 * Front-end raw character devices.  These can be bound to any block
   6 * devices to provide genuine Unix raw character device semantics.
   7 *
   8 * We reserve minor number 0 for a control interface.  ioctl()s on this
   9 * device are used to bind the other minor numbers to block devices.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/fs.h>
  14#include <linux/major.h>
  15#include <linux/blkdev.h>
  16#include <linux/backing-dev.h>
  17#include <linux/module.h>
  18#include <linux/raw.h>
  19#include <linux/capability.h>
  20#include <linux/uio.h>
  21#include <linux/cdev.h>
  22#include <linux/device.h>
  23#include <linux/mutex.h>
  24#include <linux/gfp.h>
  25#include <linux/compat.h>
  26#include <linux/vmalloc.h>
  27
  28#include <linux/uaccess.h>
  29
  30struct raw_device_data {
  31        struct block_device *binding;
  32        int inuse;
  33};
  34
  35static struct class *raw_class;
  36static struct raw_device_data *raw_devices;
  37static DEFINE_MUTEX(raw_mutex);
  38static const struct file_operations raw_ctl_fops; /* forward declaration */
  39
  40static int max_raw_minors = MAX_RAW_MINORS;
  41
  42module_param(max_raw_minors, int, 0);
  43MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)");
  44
  45/*
  46 * Open/close code for raw IO.
  47 *
  48 * We just rewrite the i_mapping for the /dev/raw/rawN file descriptor to
  49 * point at the blockdev's address_space and set the file handle to use
  50 * O_DIRECT.
  51 *
  52 * Set the device's soft blocksize to the minimum possible.  This gives the
  53 * finest possible alignment and has no adverse impact on performance.
  54 */
  55static int raw_open(struct inode *inode, struct file *filp)
  56{
  57        const int minor = iminor(inode);
  58        struct block_device *bdev;
  59        int err;
  60
  61        if (minor == 0) {       /* It is the control device */
  62                filp->f_op = &raw_ctl_fops;
  63                return 0;
  64        }
  65
  66        mutex_lock(&raw_mutex);
  67
  68        /*
  69         * All we need to do on open is check that the device is bound.
  70         */
  71        bdev = raw_devices[minor].binding;
  72        err = -ENODEV;
  73        if (!bdev)
  74                goto out;
  75        bdgrab(bdev);
  76        err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open);
  77        if (err)
  78                goto out;
  79        err = set_blocksize(bdev, bdev_logical_block_size(bdev));
  80        if (err)
  81                goto out1;
  82        filp->f_flags |= O_DIRECT;
  83        filp->f_mapping = bdev->bd_inode->i_mapping;
  84        if (++raw_devices[minor].inuse == 1)
  85                file_inode(filp)->i_mapping =
  86                        bdev->bd_inode->i_mapping;
  87        filp->private_data = bdev;
  88        mutex_unlock(&raw_mutex);
  89        return 0;
  90
  91out1:
  92        blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
  93out:
  94        mutex_unlock(&raw_mutex);
  95        return err;
  96}
  97
  98/*
  99 * When the final fd which refers to this character-special node is closed, we
 100 * make its ->mapping point back at its own i_data.
 101 */
 102static int raw_release(struct inode *inode, struct file *filp)
 103{
 104        const int minor= iminor(inode);
 105        struct block_device *bdev;
 106
 107        mutex_lock(&raw_mutex);
 108        bdev = raw_devices[minor].binding;
 109        if (--raw_devices[minor].inuse == 0)
 110                /* Here  inode->i_mapping == bdev->bd_inode->i_mapping  */
 111                inode->i_mapping = &inode->i_data;
 112        mutex_unlock(&raw_mutex);
 113
 114        blkdev_put(bdev, filp->f_mode | FMODE_EXCL);
 115        return 0;
 116}
 117
 118/*
 119 * Forward ioctls to the underlying block device.
 120 */
 121static long
 122raw_ioctl(struct file *filp, unsigned int command, unsigned long arg)
 123{
 124        struct block_device *bdev = filp->private_data;
 125        return blkdev_ioctl(bdev, 0, command, arg);
 126}
 127
 128static int bind_set(int number, u64 major, u64 minor)
 129{
 130        dev_t dev = MKDEV(major, minor);
 131        struct raw_device_data *rawdev;
 132        int err = 0;
 133
 134        if (number <= 0 || number >= max_raw_minors)
 135                return -EINVAL;
 136
 137        if (MAJOR(dev) != major || MINOR(dev) != minor)
 138                return -EINVAL;
 139
 140        rawdev = &raw_devices[number];
 141
 142        /*
 143         * This is like making block devices, so demand the
 144         * same capability
 145         */
 146        if (!capable(CAP_SYS_ADMIN))
 147                return -EPERM;
 148
 149        /*
 150         * For now, we don't need to check that the underlying
 151         * block device is present or not: we can do that when
 152         * the raw device is opened.  Just check that the
 153         * major/minor numbers make sense.
 154         */
 155
 156        if (MAJOR(dev) == 0 && dev != 0)
 157                return -EINVAL;
 158
 159        mutex_lock(&raw_mutex);
 160        if (rawdev->inuse) {
 161                mutex_unlock(&raw_mutex);
 162                return -EBUSY;
 163        }
 164        if (rawdev->binding) {
 165                bdput(rawdev->binding);
 166                module_put(THIS_MODULE);
 167        }
 168        if (!dev) {
 169                /* unbind */
 170                rawdev->binding = NULL;
 171                device_destroy(raw_class, MKDEV(RAW_MAJOR, number));
 172        } else {
 173                rawdev->binding = bdget(dev);
 174                if (rawdev->binding == NULL) {
 175                        err = -ENOMEM;
 176                } else {
 177                        dev_t raw = MKDEV(RAW_MAJOR, number);
 178                        __module_get(THIS_MODULE);
 179                        device_destroy(raw_class, raw);
 180                        device_create(raw_class, NULL, raw, NULL,
 181                                      "raw%d", number);
 182                }
 183        }
 184        mutex_unlock(&raw_mutex);
 185        return err;
 186}
 187
 188static int bind_get(int number, dev_t *dev)
 189{
 190        struct raw_device_data *rawdev;
 191        struct block_device *bdev;
 192
 193        if (number <= 0 || number >= max_raw_minors)
 194                return -EINVAL;
 195
 196        rawdev = &raw_devices[number];
 197
 198        mutex_lock(&raw_mutex);
 199        bdev = rawdev->binding;
 200        *dev = bdev ? bdev->bd_dev : 0;
 201        mutex_unlock(&raw_mutex);
 202        return 0;
 203}
 204
 205/*
 206 * Deal with ioctls against the raw-device control interface, to bind
 207 * and unbind other raw devices.
 208 */
 209static long raw_ctl_ioctl(struct file *filp, unsigned int command,
 210                          unsigned long arg)
 211{
 212        struct raw_config_request rq;
 213        dev_t dev;
 214        int err;
 215
 216        switch (command) {
 217        case RAW_SETBIND:
 218                if (copy_from_user(&rq, (void __user *) arg, sizeof(rq)))
 219                        return -EFAULT;
 220
 221                return bind_set(rq.raw_minor, rq.block_major, rq.block_minor);
 222
 223        case RAW_GETBIND:
 224                if (copy_from_user(&rq, (void __user *) arg, sizeof(rq)))
 225                        return -EFAULT;
 226
 227                err = bind_get(rq.raw_minor, &dev);
 228                if (err)
 229                        return err;
 230
 231                rq.block_major = MAJOR(dev);
 232                rq.block_minor = MINOR(dev);
 233
 234                if (copy_to_user((void __user *)arg, &rq, sizeof(rq)))
 235                        return -EFAULT;
 236
 237                return 0;
 238        }
 239
 240        return -EINVAL;
 241}
 242
 243#ifdef CONFIG_COMPAT
 244struct raw32_config_request {
 245        compat_int_t    raw_minor;
 246        compat_u64      block_major;
 247        compat_u64      block_minor;
 248};
 249
 250static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
 251                                unsigned long arg)
 252{
 253        struct raw32_config_request __user *user_req = compat_ptr(arg);
 254        struct raw32_config_request rq;
 255        dev_t dev;
 256        int err = 0;
 257
 258        switch (cmd) {
 259        case RAW_SETBIND:
 260                if (copy_from_user(&rq, user_req, sizeof(rq)))
 261                        return -EFAULT;
 262
 263                return bind_set(rq.raw_minor, rq.block_major, rq.block_minor);
 264
 265        case RAW_GETBIND:
 266                if (copy_from_user(&rq, user_req, sizeof(rq)))
 267                        return -EFAULT;
 268
 269                err = bind_get(rq.raw_minor, &dev);
 270                if (err)
 271                        return err;
 272
 273                rq.block_major = MAJOR(dev);
 274                rq.block_minor = MINOR(dev);
 275
 276                if (copy_to_user(user_req, &rq, sizeof(rq)))
 277                        return -EFAULT;
 278
 279                return 0;
 280        }
 281
 282        return -EINVAL;
 283}
 284#endif
 285
 286static const struct file_operations raw_fops = {
 287        .read_iter      = blkdev_read_iter,
 288        .write_iter     = blkdev_write_iter,
 289        .fsync          = blkdev_fsync,
 290        .open           = raw_open,
 291        .release        = raw_release,
 292        .unlocked_ioctl = raw_ioctl,
 293        .llseek         = default_llseek,
 294        .owner          = THIS_MODULE,
 295};
 296
 297static const struct file_operations raw_ctl_fops = {
 298        .unlocked_ioctl = raw_ctl_ioctl,
 299#ifdef CONFIG_COMPAT
 300        .compat_ioctl   = raw_ctl_compat_ioctl,
 301#endif
 302        .open           = raw_open,
 303        .owner          = THIS_MODULE,
 304        .llseek         = noop_llseek,
 305};
 306
 307static struct cdev raw_cdev;
 308
 309static char *raw_devnode(struct device *dev, umode_t *mode)
 310{
 311        return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev));
 312}
 313
 314static int __init raw_init(void)
 315{
 316        dev_t dev = MKDEV(RAW_MAJOR, 0);
 317        int ret;
 318
 319        if (max_raw_minors < 1 || max_raw_minors > 65536) {
 320                printk(KERN_WARNING "raw: invalid max_raw_minors (must be"
 321                        " between 1 and 65536), using %d\n", MAX_RAW_MINORS);
 322                max_raw_minors = MAX_RAW_MINORS;
 323        }
 324
 325        raw_devices = vzalloc(array_size(max_raw_minors,
 326                                         sizeof(struct raw_device_data)));
 327        if (!raw_devices) {
 328                printk(KERN_ERR "Not enough memory for raw device structures\n");
 329                ret = -ENOMEM;
 330                goto error;
 331        }
 332
 333        ret = register_chrdev_region(dev, max_raw_minors, "raw");
 334        if (ret)
 335                goto error;
 336
 337        cdev_init(&raw_cdev, &raw_fops);
 338        ret = cdev_add(&raw_cdev, dev, max_raw_minors);
 339        if (ret)
 340                goto error_region;
 341        raw_class = class_create(THIS_MODULE, "raw");
 342        if (IS_ERR(raw_class)) {
 343                printk(KERN_ERR "Error creating raw class.\n");
 344                cdev_del(&raw_cdev);
 345                ret = PTR_ERR(raw_class);
 346                goto error_region;
 347        }
 348        raw_class->devnode = raw_devnode;
 349        device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 350
 351        return 0;
 352
 353error_region:
 354        unregister_chrdev_region(dev, max_raw_minors);
 355error:
 356        vfree(raw_devices);
 357        return ret;
 358}
 359
 360static void __exit raw_exit(void)
 361{
 362        device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
 363        class_destroy(raw_class);
 364        cdev_del(&raw_cdev);
 365        unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors);
 366}
 367
 368module_init(raw_init);
 369module_exit(raw_exit);
 370MODULE_LICENSE("GPL");
 371