at v4.20-rc2 5.0 kB view raw
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 29enum { 30 Opt_gid, Opt_hidepid, Opt_err, 31}; 32 33static const match_table_t tokens = { 34 {Opt_hidepid, "hidepid=%u"}, 35 {Opt_gid, "gid=%u"}, 36 {Opt_err, NULL}, 37}; 38 39int 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 81int 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 89static 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 104static 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 117static 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 124void __init proc_root_init(void) 125{ 126 proc_init_kmemcache(); 127 set_proc_pid_nlink(); 128 proc_self_init(); 129 proc_thread_self_init(); 130 proc_symlink("mounts", NULL, "self/mounts"); 131 132 proc_net_init(); 133 proc_mkdir("fs", NULL); 134 proc_mkdir("driver", NULL); 135 proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */ 136#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) 137 /* just give it a mountpoint */ 138 proc_create_mount_point("openprom"); 139#endif 140 proc_tty_init(); 141 proc_mkdir("bus", NULL); 142 proc_sys_init(); 143 144 register_filesystem(&proc_fs_type); 145} 146 147static int proc_root_getattr(const struct path *path, struct kstat *stat, 148 u32 request_mask, unsigned int query_flags) 149{ 150 generic_fillattr(d_inode(path->dentry), stat); 151 stat->nlink = proc_root.nlink + nr_processes(); 152 return 0; 153} 154 155static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) 156{ 157 if (!proc_pid_lookup(dir, dentry, flags)) 158 return NULL; 159 160 return proc_lookup(dir, dentry, flags); 161} 162 163static int proc_root_readdir(struct file *file, struct dir_context *ctx) 164{ 165 if (ctx->pos < FIRST_PROCESS_ENTRY) { 166 int error = proc_readdir(file, ctx); 167 if (unlikely(error <= 0)) 168 return error; 169 ctx->pos = FIRST_PROCESS_ENTRY; 170 } 171 172 return proc_pid_readdir(file, ctx); 173} 174 175/* 176 * The root /proc directory is special, as it has the 177 * <pid> directories. Thus we don't use the generic 178 * directory handling functions for that.. 179 */ 180static const struct file_operations proc_root_operations = { 181 .read = generic_read_dir, 182 .iterate_shared = proc_root_readdir, 183 .llseek = generic_file_llseek, 184}; 185 186/* 187 * proc root can do almost nothing.. 188 */ 189static const struct inode_operations proc_root_inode_operations = { 190 .lookup = proc_root_lookup, 191 .getattr = proc_root_getattr, 192}; 193 194/* 195 * This is the root "inode" in the /proc tree.. 196 */ 197struct proc_dir_entry proc_root = { 198 .low_ino = PROC_ROOT_INO, 199 .namelen = 5, 200 .mode = S_IFDIR | S_IRUGO | S_IXUGO, 201 .nlink = 2, 202 .refcnt = REFCOUNT_INIT(1), 203 .proc_iops = &proc_root_inode_operations, 204 .proc_fops = &proc_root_operations, 205 .parent = &proc_root, 206 .subdir = RB_ROOT, 207 .name = "/proc", 208}; 209 210int pid_ns_prepare_proc(struct pid_namespace *ns) 211{ 212 struct vfsmount *mnt; 213 214 mnt = kern_mount_data(&proc_fs_type, ns); 215 if (IS_ERR(mnt)) 216 return PTR_ERR(mnt); 217 218 ns->proc_mnt = mnt; 219 return 0; 220} 221 222void pid_ns_release_proc(struct pid_namespace *ns) 223{ 224 kern_unmount(ns->proc_mnt); 225}