cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

devtmpfs.c (10433B)


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