Branch data Line data Source code
1 : : /*
2 : : * fs/sysfs/symlink.c - operations for initializing and mounting sysfs
3 : : *
4 : : * Copyright (c) 2001-3 Patrick Mochel
5 : : * Copyright (c) 2007 SUSE Linux Products GmbH
6 : : * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 : : *
8 : : * This file is released under the GPLv2.
9 : : *
10 : : * Please see Documentation/filesystems/sysfs.txt for more information.
11 : : */
12 : :
13 : : #define DEBUG
14 : :
15 : : #include <linux/fs.h>
16 : : #include <linux/mount.h>
17 : : #include <linux/init.h>
18 : : #include <linux/user_namespace.h>
19 : :
20 : : #include "sysfs.h"
21 : :
22 : : static struct kernfs_root *sysfs_root;
23 : : struct kernfs_node *sysfs_root_kn;
24 : :
25 : 0 : static struct dentry *sysfs_mount(struct file_system_type *fs_type,
26 : : int flags, const char *dev_name, void *data)
27 : : {
28 : : struct dentry *root;
29 : : void *ns;
30 : : bool new_sb;
31 : :
32 [ # # ]: 0 : if (!(flags & MS_KERNMOUNT)) {
33 [ # # ][ # # ]: 0 : if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
34 : : return ERR_PTR(-EPERM);
35 : :
36 [ # # ]: 0 : if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET))
37 : : return ERR_PTR(-EPERM);
38 : : }
39 : :
40 : 0 : ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET);
41 : 0 : root = kernfs_mount_ns(fs_type, flags, sysfs_root, &new_sb, ns);
42 [ # # ][ # # ]: 0 : if (IS_ERR(root) || !new_sb)
43 : 0 : kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
44 : 0 : return root;
45 : : }
46 : :
47 : 0 : static void sysfs_kill_sb(struct super_block *sb)
48 : : {
49 : 0 : void *ns = (void *)kernfs_super_ns(sb);
50 : :
51 : 0 : kernfs_kill_sb(sb);
52 : 0 : kobj_ns_drop(KOBJ_NS_TYPE_NET, ns);
53 : 0 : }
54 : :
55 : : static struct file_system_type sysfs_fs_type = {
56 : : .name = "sysfs",
57 : : .mount = sysfs_mount,
58 : : .kill_sb = sysfs_kill_sb,
59 : : .fs_flags = FS_USERNS_MOUNT,
60 : : };
61 : :
62 : 0 : int __init sysfs_init(void)
63 : : {
64 : : int err;
65 : :
66 : 0 : sysfs_root = kernfs_create_root(NULL, NULL);
67 [ # # ]: 0 : if (IS_ERR(sysfs_root))
68 : 0 : return PTR_ERR(sysfs_root);
69 : :
70 : 0 : sysfs_root_kn = sysfs_root->kn;
71 : :
72 : 0 : err = register_filesystem(&sysfs_fs_type);
73 [ # # ]: 0 : if (err) {
74 : 0 : kernfs_destroy_root(sysfs_root);
75 : 0 : return err;
76 : : }
77 : :
78 : : return 0;
79 : : }
|