1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/fs/proc/root.c 4 * 5 * Copyright (C) 1991, 1992 Linus Torvalds 6 * 7 * proc root directory handling functions 8 */ 9 10 #include <linux/uaccess.h> 11 12 #include <linux/errno.h> 13 #include <linux/time.h> 14 #include <linux/proc_fs.h> 15 #include <linux/stat.h> 16 #include <linux/init.h> 17 #include <linux/sched.h> 18 #include <linux/sched/stat.h> 19 #include <linux/module.h> 20 #include <linux/bitops.h> 21 #include <linux/user_namespace.h> 22 #include <linux/mount.h> 23 #include <linux/pid_namespace.h> 24 #include <linux/parser.h> 25 #include <linux/cred.h> 26 27 #include "internal.h" 28 29 enum { 30 Opt_gid, Opt_hidepid, Opt_err, 31 }; 32 33 static const match_table_t tokens = { 34 {Opt_hidepid, "hidepid=%u"}, 35 {Opt_gid, "gid=%u"}, 36 {Opt_err, NULL}, 37 }; 38 39 int proc_parse_options(char *options, struct pid_namespace *pid) 40 { 41 char *p; 42 substring_t args[MAX_OPT_ARGS]; 43 int option; 44 45 if (!options) 46 return 1; 47 48 while ((p = strsep(&options, ",")) != NULL) { 49 int token; 50 if (!*p) 51 continue; 52 53 args[0].to = args[0].from = NULL; 54 token = match_token(p, tokens, args); 55 switch (token) { 56 case Opt_gid: 57 if (match_int(&args[0], &option)) 58 return 0; 59 pid->pid_gid = make_kgid(current_user_ns(), option); 60 break; 61 case Opt_hidepid: 62 if (match_int(&args[0], &option)) 63 return 0; 64 if (option < HIDEPID_OFF || 65 option > HIDEPID_INVISIBLE) { 66 pr_err("proc: hidepid value must be between 0 and 2.\n"); 67 return 0; 68 } 69 pid->hide_pid = option; 70 break; 71 default: 72 pr_err("proc: unrecognized mount option \"%s\" " 73 "or missing value\n", p); 74 return 0; 75 } 76 } 77 78 return 1; 79 } 80 81 int proc_remount(struct super_block *sb, int *flags, char *data) 82 { 83 struct pid_namespace *pid = sb->s_fs_info; 84 85 sync_filesystem(sb); 86 return !proc_parse_options(data, pid); 87 } 88 89 static struct dentry *proc_mount(struct file_system_type *fs_type, 90 int flags, const char *dev_name, void *data) 91 { 92 struct pid_namespace *ns; 93 94 if (flags & SB_KERNMOUNT) { 95 ns = data; 96 data = NULL; 97 } else { 98 ns = task_active_pid_ns(current); 99 } 100 101 return mount_ns(fs_type, flags, data, ns, ns->user_ns, proc_fill_super); 102 } 103 104 static void proc_kill_sb(struct super_block *sb) 105 { 106 struct pid_namespace *ns; 107 108 ns = (struct pid_namespace *)sb->s_fs_info; 109 if (ns->proc_self) 110 dput(ns->proc_self); 111 if (ns->proc_thread_self) 112 dput(ns->proc_thread_self); 113 kill_anon_super(sb); 114 put_pid_ns(ns); 115 } 116 117 static struct file_system_type proc_fs_type = { 118 .name = "proc", 119 .mount = proc_mount, 120 .kill_sb = proc_kill_sb, 121 .fs_flags = FS_USERNS_MOUNT, 122 }; 123 124 void __init proc_root_init(void) 125 { 126 int err; 127 128 proc_init_inodecache(); 129 set_proc_pid_nlink(); 130 err = register_filesystem(&proc_fs_type); 131 if (err) 132 return; 133 134 proc_self_init(); 135 proc_thread_self_init(); 136 proc_symlink("mounts", NULL, "self/mounts"); 137 138 proc_net_init(); 139 140 #ifdef CONFIG_SYSVIPC 141 proc_mkdir("sysvipc", NULL); 142 #endif 143 proc_mkdir("fs", NULL); 144 proc_mkdir("driver", NULL); 145 proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */ 146 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) 147 /* just give it a mountpoint */ 148 proc_create_mount_point("openprom"); 149 #endif 150 proc_tty_init(); 151 proc_mkdir("bus", NULL); 152 proc_sys_init(); 153 } 154 155 static int proc_root_getattr(const struct path *path, struct kstat *stat, 156 u32 request_mask, unsigned int query_flags) 157 { 158 generic_fillattr(d_inode(path->dentry), stat); 159 stat->nlink = proc_root.nlink + nr_processes(); 160 return 0; 161 } 162 163 static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) 164 { 165 if (!proc_pid_lookup(dir, dentry, flags)) 166 return NULL; 167 168 return proc_lookup(dir, dentry, flags); 169 } 170 171 static int proc_root_readdir(struct file *file, struct dir_context *ctx) 172 { 173 if (ctx->pos < FIRST_PROCESS_ENTRY) { 174 int error = proc_readdir(file, ctx); 175 if (unlikely(error <= 0)) 176 return error; 177 ctx->pos = FIRST_PROCESS_ENTRY; 178 } 179 180 return proc_pid_readdir(file, ctx); 181 } 182 183 /* 184 * The root /proc directory is special, as it has the 185 * <pid> directories. Thus we don't use the generic 186 * directory handling functions for that.. 187 */ 188 static const struct file_operations proc_root_operations = { 189 .read = generic_read_dir, 190 .iterate_shared = proc_root_readdir, 191 .llseek = generic_file_llseek, 192 }; 193 194 /* 195 * proc root can do almost nothing.. 196 */ 197 static const struct inode_operations proc_root_inode_operations = { 198 .lookup = proc_root_lookup, 199 .getattr = proc_root_getattr, 200 }; 201 202 /* 203 * This is the root "inode" in the /proc tree.. 204 */ 205 struct proc_dir_entry proc_root = { 206 .low_ino = PROC_ROOT_INO, 207 .namelen = 5, 208 .mode = S_IFDIR | S_IRUGO | S_IXUGO, 209 .nlink = 2, 210 .count = ATOMIC_INIT(1), 211 .proc_iops = &proc_root_inode_operations, 212 .proc_fops = &proc_root_operations, 213 .parent = &proc_root, 214 .subdir = RB_ROOT_CACHED, 215 .name = "/proc", 216 }; 217 218 int pid_ns_prepare_proc(struct pid_namespace *ns) 219 { 220 struct vfsmount *mnt; 221 222 mnt = kern_mount_data(&proc_fs_type, ns); 223 if (IS_ERR(mnt)) 224 return PTR_ERR(mnt); 225 226 ns->proc_mnt = mnt; 227 return 0; 228 } 229 230 void pid_ns_release_proc(struct pid_namespace *ns) 231 { 232 kern_unmount(ns->proc_mnt); 233 } 234