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