LCOV - code coverage report
Current view: top level - drivers/base - devtmpfs.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 137 229 59.8 %
Date: 2021-04-22 12:43:58 Functions: 12 18 66.7 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * devtmpfs - kernel-maintained tmpfs-based /dev
       4             :  *
       5             :  * Copyright (C) 2009, Kay Sievers <kay.sievers@vrfy.org>
       6             :  *
       7             :  * During bootup, before any driver core device is registered,
       8             :  * devtmpfs, a tmpfs-based filesystem is created. Every driver-core
       9             :  * device which requests a device node, will add a node in this
      10             :  * filesystem.
      11             :  * By default, all devices are named after the name of the device,
      12             :  * owned by root and have a default mode of 0600. Subsystems can
      13             :  * overwrite the default setting if needed.
      14             :  */
      15             : 
      16             : #include <linux/kernel.h>
      17             : #include <linux/syscalls.h>
      18             : #include <linux/mount.h>
      19             : #include <linux/device.h>
      20             : #include <linux/genhd.h>
      21             : #include <linux/namei.h>
      22             : #include <linux/fs.h>
      23             : #include <linux/shmem_fs.h>
      24             : #include <linux/ramfs.h>
      25             : #include <linux/sched.h>
      26             : #include <linux/slab.h>
      27             : #include <linux/kthread.h>
      28             : #include <linux/init_syscalls.h>
      29             : #include <uapi/linux/mount.h>
      30             : #include "base.h"
      31             : 
      32             : static struct task_struct *thread;
      33             : 
      34             : static int __initdata mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT);
      35             : 
      36             : static DEFINE_SPINLOCK(req_lock);
      37             : 
      38             : static struct req {
      39             :         struct req *next;
      40             :         struct completion done;
      41             :         int err;
      42             :         const char *name;
      43             :         umode_t mode;   /* 0 => delete */
      44             :         kuid_t uid;
      45             :         kgid_t gid;
      46             :         struct device *dev;
      47             : } *requests;
      48             : 
      49           0 : static int __init mount_param(char *str)
      50             : {
      51           0 :         mount_dev = simple_strtoul(str, NULL, 0);
      52           0 :         return 1;
      53             : }
      54             : __setup("devtmpfs.mount=", mount_param);
      55             : 
      56             : static struct vfsmount *mnt;
      57             : 
      58           2 : static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags,
      59             :                       const char *dev_name, void *data)
      60             : {
      61           2 :         struct super_block *s = mnt->mnt_sb;
      62           2 :         atomic_inc(&s->s_active);
      63           2 :         down_write(&s->s_umount);
      64           2 :         return dget(s->s_root);
      65             : }
      66             : 
      67             : static struct file_system_type internal_fs_type = {
      68             :         .name = "devtmpfs",
      69             : #ifdef CONFIG_TMPFS
      70             :         .init_fs_context = shmem_init_fs_context,
      71             :         .parameters     = shmem_fs_parameters,
      72             : #else
      73             :         .init_fs_context = ramfs_init_fs_context,
      74             :         .parameters     = ramfs_fs_parameters,
      75             : #endif
      76             :         .kill_sb = kill_litter_super,
      77             : };
      78             : 
      79             : static struct file_system_type dev_fs_type = {
      80             :         .name = "devtmpfs",
      81             :         .mount = public_dev_mount,
      82             : };
      83             : 
      84             : #ifdef CONFIG_BLOCK
      85         111 : static inline int is_blockdev(struct device *dev)
      86             : {
      87         111 :         return dev->class == &block_class;
      88             : }
      89             : #else
      90             : static inline int is_blockdev(struct device *dev) { return 0; }
      91             : #endif
      92             : 
      93         111 : static int devtmpfs_submit_req(struct req *req, const char *tmp)
      94             : {
      95         111 :         init_completion(&req->done);
      96             : 
      97         111 :         spin_lock(&req_lock);
      98         111 :         req->next = requests;
      99         111 :         requests = req;
     100         111 :         spin_unlock(&req_lock);
     101             : 
     102         111 :         wake_up_process(thread);
     103         111 :         wait_for_completion(&req->done);
     104             : 
     105         111 :         kfree(tmp);
     106             : 
     107         111 :         return req->err;
     108             : }
     109             : 
     110         111 : int devtmpfs_create_node(struct device *dev)
     111             : {
     112         111 :         const char *tmp = NULL;
     113         111 :         struct req req;
     114             : 
     115         111 :         if (!thread)
     116             :                 return 0;
     117             : 
     118         111 :         req.mode = 0;
     119         111 :         req.uid = GLOBAL_ROOT_UID;
     120         111 :         req.gid = GLOBAL_ROOT_GID;
     121         111 :         req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp);
     122         111 :         if (!req.name)
     123             :                 return -ENOMEM;
     124             : 
     125         111 :         if (req.mode == 0)
     126         103 :                 req.mode = 0600;
     127         111 :         if (is_blockdev(dev))
     128          10 :                 req.mode |= S_IFBLK;
     129             :         else
     130         101 :                 req.mode |= S_IFCHR;
     131             : 
     132         111 :         req.dev = dev;
     133             : 
     134         111 :         return devtmpfs_submit_req(&req, tmp);
     135             : }
     136             : 
     137           0 : int devtmpfs_delete_node(struct device *dev)
     138             : {
     139           0 :         const char *tmp = NULL;
     140           0 :         struct req req;
     141             : 
     142           0 :         if (!thread)
     143             :                 return 0;
     144             : 
     145           0 :         req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp);
     146           0 :         if (!req.name)
     147             :                 return -ENOMEM;
     148             : 
     149           0 :         req.mode = 0;
     150           0 :         req.dev = dev;
     151             : 
     152           0 :         return devtmpfs_submit_req(&req, tmp);
     153             : }
     154             : 
     155           1 : static int dev_mkdir(const char *name, umode_t mode)
     156             : {
     157           1 :         struct dentry *dentry;
     158           1 :         struct path path;
     159           1 :         int err;
     160             : 
     161           1 :         dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY);
     162           1 :         if (IS_ERR(dentry))
     163           0 :                 return PTR_ERR(dentry);
     164             : 
     165           1 :         err = vfs_mkdir(&init_user_ns, d_inode(path.dentry), dentry, mode);
     166           1 :         if (!err)
     167             :                 /* mark as kernel-created inode */
     168           1 :                 d_inode(dentry)->i_private = &thread;
     169           1 :         done_path_create(&path, dentry);
     170           1 :         return err;
     171             : }
     172             : 
     173           1 : static int create_path(const char *nodepath)
     174             : {
     175           1 :         char *path;
     176           1 :         char *s;
     177           1 :         int err = 0;
     178             : 
     179             :         /* parent directories do not exist, create them */
     180           1 :         path = kstrdup(nodepath, GFP_KERNEL);
     181           1 :         if (!path)
     182             :                 return -ENOMEM;
     183             : 
     184             :         s = path;
     185           3 :         for (;;) {
     186           3 :                 s = strchr(s, '/');
     187           2 :                 if (!s)
     188             :                         break;
     189           1 :                 s[0] = '\0';
     190           1 :                 err = dev_mkdir(path, 0755);
     191           1 :                 if (err && err != -EEXIST)
     192             :                         break;
     193           1 :                 s[0] = '/';
     194           1 :                 s++;
     195             :         }
     196           1 :         kfree(path);
     197           1 :         return err;
     198             : }
     199             : 
     200         111 : static int handle_create(const char *nodename, umode_t mode, kuid_t uid,
     201             :                          kgid_t gid, struct device *dev)
     202             : {
     203         111 :         struct dentry *dentry;
     204         111 :         struct path path;
     205         111 :         int err;
     206             : 
     207         111 :         dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
     208         111 :         if (dentry == ERR_PTR(-ENOENT)) {
     209           1 :                 create_path(nodename);
     210           1 :                 dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
     211             :         }
     212         111 :         if (IS_ERR(dentry))
     213           0 :                 return PTR_ERR(dentry);
     214             : 
     215         111 :         err = vfs_mknod(&init_user_ns, d_inode(path.dentry), dentry, mode,
     216             :                         dev->devt);
     217         111 :         if (!err) {
     218         111 :                 struct iattr newattrs;
     219             : 
     220         111 :                 newattrs.ia_mode = mode;
     221         111 :                 newattrs.ia_uid = uid;
     222         111 :                 newattrs.ia_gid = gid;
     223         111 :                 newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID;
     224         111 :                 inode_lock(d_inode(dentry));
     225         111 :                 notify_change(&init_user_ns, dentry, &newattrs, NULL);
     226         111 :                 inode_unlock(d_inode(dentry));
     227             : 
     228             :                 /* mark as kernel-created inode */
     229         111 :                 d_inode(dentry)->i_private = &thread;
     230             :         }
     231         111 :         done_path_create(&path, dentry);
     232         111 :         return err;
     233             : }
     234             : 
     235           0 : static int dev_rmdir(const char *name)
     236             : {
     237           0 :         struct path parent;
     238           0 :         struct dentry *dentry;
     239           0 :         int err;
     240             : 
     241           0 :         dentry = kern_path_locked(name, &parent);
     242           0 :         if (IS_ERR(dentry))
     243           0 :                 return PTR_ERR(dentry);
     244           0 :         if (d_really_is_positive(dentry)) {
     245           0 :                 if (d_inode(dentry)->i_private == &thread)
     246           0 :                         err = vfs_rmdir(&init_user_ns, d_inode(parent.dentry),
     247             :                                         dentry);
     248             :                 else
     249             :                         err = -EPERM;
     250             :         } else {
     251             :                 err = -ENOENT;
     252             :         }
     253           0 :         dput(dentry);
     254           0 :         inode_unlock(d_inode(parent.dentry));
     255           0 :         path_put(&parent);
     256           0 :         return err;
     257             : }
     258             : 
     259           0 : static int delete_path(const char *nodepath)
     260             : {
     261           0 :         char *path;
     262           0 :         int err = 0;
     263             : 
     264           0 :         path = kstrdup(nodepath, GFP_KERNEL);
     265           0 :         if (!path)
     266             :                 return -ENOMEM;
     267             : 
     268           0 :         for (;;) {
     269           0 :                 char *base;
     270             : 
     271           0 :                 base = strrchr(path, '/');
     272           0 :                 if (!base)
     273             :                         break;
     274           0 :                 base[0] = '\0';
     275           0 :                 err = dev_rmdir(path);
     276           0 :                 if (err)
     277             :                         break;
     278             :         }
     279             : 
     280           0 :         kfree(path);
     281           0 :         return err;
     282             : }
     283             : 
     284           0 : static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *stat)
     285             : {
     286             :         /* did we create it */
     287           0 :         if (inode->i_private != &thread)
     288             :                 return 0;
     289             : 
     290             :         /* does the dev_t match */
     291           0 :         if (is_blockdev(dev)) {
     292           0 :                 if (!S_ISBLK(stat->mode))
     293             :                         return 0;
     294             :         } else {
     295           0 :                 if (!S_ISCHR(stat->mode))
     296             :                         return 0;
     297             :         }
     298           0 :         if (stat->rdev != dev->devt)
     299           0 :                 return 0;
     300             : 
     301             :         /* ours */
     302             :         return 1;
     303             : }
     304             : 
     305           0 : static int handle_remove(const char *nodename, struct device *dev)
     306             : {
     307           0 :         struct path parent;
     308           0 :         struct dentry *dentry;
     309           0 :         int deleted = 0;
     310           0 :         int err;
     311             : 
     312           0 :         dentry = kern_path_locked(nodename, &parent);
     313           0 :         if (IS_ERR(dentry))
     314           0 :                 return PTR_ERR(dentry);
     315             : 
     316           0 :         if (d_really_is_positive(dentry)) {
     317           0 :                 struct kstat stat;
     318           0 :                 struct path p = {.mnt = parent.mnt, .dentry = dentry};
     319           0 :                 err = vfs_getattr(&p, &stat, STATX_TYPE | STATX_MODE,
     320             :                                   AT_STATX_SYNC_AS_STAT);
     321           0 :                 if (!err && dev_mynode(dev, d_inode(dentry), &stat)) {
     322           0 :                         struct iattr newattrs;
     323             :                         /*
     324             :                          * before unlinking this node, reset permissions
     325             :                          * of possible references like hardlinks
     326             :                          */
     327           0 :                         newattrs.ia_uid = GLOBAL_ROOT_UID;
     328           0 :                         newattrs.ia_gid = GLOBAL_ROOT_GID;
     329           0 :                         newattrs.ia_mode = stat.mode & ~0777;
     330           0 :                         newattrs.ia_valid =
     331             :                                 ATTR_UID|ATTR_GID|ATTR_MODE;
     332           0 :                         inode_lock(d_inode(dentry));
     333           0 :                         notify_change(&init_user_ns, dentry, &newattrs, NULL);
     334           0 :                         inode_unlock(d_inode(dentry));
     335           0 :                         err = vfs_unlink(&init_user_ns, d_inode(parent.dentry),
     336             :                                          dentry, NULL);
     337           0 :                         if (!err || err == -ENOENT)
     338           0 :                                 deleted = 1;
     339             :                 }
     340             :         } else {
     341             :                 err = -ENOENT;
     342             :         }
     343           0 :         dput(dentry);
     344           0 :         inode_unlock(d_inode(parent.dentry));
     345             : 
     346           0 :         path_put(&parent);
     347           0 :         if (deleted && strchr(nodename, '/'))
     348           0 :                 delete_path(nodename);
     349             :         return err;
     350             : }
     351             : 
     352             : /*
     353             :  * If configured, or requested by the commandline, devtmpfs will be
     354             :  * auto-mounted after the kernel mounted the root filesystem.
     355             :  */
     356           1 : int __init devtmpfs_mount(void)
     357             : {
     358           1 :         int err;
     359             : 
     360           1 :         if (!mount_dev)
     361             :                 return 0;
     362             : 
     363           1 :         if (!thread)
     364             :                 return 0;
     365             : 
     366           1 :         err = init_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
     367           1 :         if (err)
     368           0 :                 printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
     369             :         else
     370           1 :                 printk(KERN_INFO "devtmpfs: mounted\n");
     371             :         return err;
     372             : }
     373             : 
     374             : static DECLARE_COMPLETION(setup_done);
     375             : 
     376         111 : static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
     377             :                   struct device *dev)
     378             : {
     379         111 :         if (mode)
     380         111 :                 return handle_create(name, mode, uid, gid, dev);
     381             :         else
     382           0 :                 return handle_remove(name, dev);
     383             : }
     384             : 
     385           1 : static void __noreturn devtmpfs_work_loop(void)
     386             : {
     387         224 :         while (1) {
     388         112 :                 spin_lock(&req_lock);
     389         223 :                 while (requests) {
     390         111 :                         struct req *req = requests;
     391         111 :                         requests = NULL;
     392         111 :                         spin_unlock(&req_lock);
     393         222 :                         while (req) {
     394         111 :                                 struct req *next = req->next;
     395         111 :                                 req->err = handle(req->name, req->mode,
     396             :                                                   req->uid, req->gid, req->dev);
     397         111 :                                 complete(&req->done);
     398         111 :                                 req = next;
     399             :                         }
     400         334 :                         spin_lock(&req_lock);
     401             :                 }
     402         112 :                 __set_current_state(TASK_INTERRUPTIBLE);
     403         112 :                 spin_unlock(&req_lock);
     404         112 :                 schedule();
     405             :         }
     406             : }
     407             : 
     408           1 : static int __init devtmpfs_setup(void *p)
     409             : {
     410           1 :         int err;
     411             : 
     412           1 :         err = ksys_unshare(CLONE_NEWNS);
     413           1 :         if (err)
     414           0 :                 goto out;
     415           1 :         err = init_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
     416           1 :         if (err)
     417           0 :                 goto out;
     418           1 :         init_chdir("/.."); /* will traverse into overmounted root */
     419           1 :         init_chroot(".");
     420           1 : out:
     421           1 :         *(int *)p = err;
     422           1 :         complete(&setup_done);
     423           1 :         return err;
     424             : }
     425             : 
     426             : /*
     427             :  * The __ref is because devtmpfs_setup needs to be __init for the routines it
     428             :  * calls.  That call is done while devtmpfs_init, which is marked __init,
     429             :  * synchronously waits for it to complete.
     430             :  */
     431           1 : static int __ref devtmpfsd(void *p)
     432             : {
     433           1 :         int err = devtmpfs_setup(p);
     434             : 
     435           1 :         if (err)
     436           0 :                 return err;
     437           1 :         devtmpfs_work_loop();
     438             :         return 0;
     439             : }
     440             : 
     441             : /*
     442             :  * Create devtmpfs instance, driver-core devices will add their device
     443             :  * nodes here.
     444             :  */
     445           1 : int __init devtmpfs_init(void)
     446             : {
     447           1 :         char opts[] = "mode=0755";
     448           1 :         int err;
     449             : 
     450           1 :         mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts);
     451           1 :         if (IS_ERR(mnt)) {
     452           0 :                 printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n",
     453             :                                 PTR_ERR(mnt));
     454           0 :                 return PTR_ERR(mnt);
     455             :         }
     456           1 :         err = register_filesystem(&dev_fs_type);
     457           1 :         if (err) {
     458           0 :                 printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
     459             :                        "type %i\n", err);
     460           0 :                 return err;
     461             :         }
     462             : 
     463           1 :         thread = kthread_run(devtmpfsd, &err, "kdevtmpfs");
     464           1 :         if (!IS_ERR(thread)) {
     465           1 :                 wait_for_completion(&setup_done);
     466             :         } else {
     467           0 :                 err = PTR_ERR(thread);
     468           0 :                 thread = NULL;
     469             :         }
     470             : 
     471           1 :         if (err) {
     472           0 :                 printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
     473           0 :                 unregister_filesystem(&dev_fs_type);
     474           0 :                 return err;
     475             :         }
     476             : 
     477           1 :         printk(KERN_INFO "devtmpfs: initialized\n");
     478           1 :         return 0;
     479             : }

Generated by: LCOV version 1.14