Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  linux/fs/proc/root.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  proc root directory handling functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/sched/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/user_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/pid_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/fs_parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/cred.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/magic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) struct proc_fs_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct pid_namespace	*pid_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	unsigned int		mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	enum proc_hidepid	hidepid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	int			gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	enum proc_pidonly	pidonly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) enum proc_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	Opt_gid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	Opt_hidepid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	Opt_subset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static const struct fs_parameter_spec proc_fs_parameters[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	fsparam_u32("gid",	Opt_gid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	fsparam_string("hidepid",	Opt_hidepid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	fsparam_string("subset",	Opt_subset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static inline int valid_hidepid(unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	return (value == HIDEPID_OFF ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		value == HIDEPID_NO_ACCESS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		value == HIDEPID_INVISIBLE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		value == HIDEPID_NOT_PTRACEABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static int proc_parse_hidepid_param(struct fs_context *fc, struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct proc_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	struct fs_parameter_spec hidepid_u32_spec = fsparam_u32("hidepid", Opt_hidepid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct fs_parse_result result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int base = (unsigned long)hidepid_u32_spec.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (param->type != fs_value_is_string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		return invalf(fc, "proc: unexpected type of hidepid value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (!kstrtouint(param->string, base, &result.uint_32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		if (!valid_hidepid(result.uint_32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			return invalf(fc, "proc: unknown value of hidepid - %s\n", param->string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		ctx->hidepid = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (!strcmp(param->string, "off"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		ctx->hidepid = HIDEPID_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	else if (!strcmp(param->string, "noaccess"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		ctx->hidepid = HIDEPID_NO_ACCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	else if (!strcmp(param->string, "invisible"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		ctx->hidepid = HIDEPID_INVISIBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	else if (!strcmp(param->string, "ptraceable"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		ctx->hidepid = HIDEPID_NOT_PTRACEABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		return invalf(fc, "proc: unknown value of hidepid - %s\n", param->string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) static int proc_parse_subset_param(struct fs_context *fc, char *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	struct proc_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	while (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		char *ptr = strchr(value, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		if (ptr != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			*ptr++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		if (*value != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			if (!strcmp(value, "pid")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 				ctx->pidonly = PROC_PIDONLY_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 				return invalf(fc, "proc: unsupported subset option - %s\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		value = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct proc_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct fs_parse_result result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	opt = fs_parse(fc, proc_fs_parameters, param, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (opt < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		return opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	case Opt_gid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		ctx->gid = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	case Opt_hidepid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		if (proc_parse_hidepid_param(fc, param))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	case Opt_subset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		if (proc_parse_subset_param(fc, param->string) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	ctx->mask |= 1 << opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static void proc_apply_options(struct proc_fs_info *fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			       struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			       struct user_namespace *user_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct proc_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	if (ctx->mask & (1 << Opt_gid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		fs_info->pid_gid = make_kgid(user_ns, ctx->gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (ctx->mask & (1 << Opt_hidepid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		fs_info->hide_pid = ctx->hidepid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (ctx->mask & (1 << Opt_subset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		fs_info->pidonly = ctx->pidonly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int proc_fill_super(struct super_block *s, struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct proc_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	struct inode *root_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	struct proc_fs_info *fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	fs_info = kzalloc(sizeof(*fs_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (!fs_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	fs_info->pid_ns = get_pid_ns(ctx->pid_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	proc_apply_options(fs_info, fc, current_user_ns());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	/* User space would break if executables or devices appear on proc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	s->s_iflags |= SB_I_USERNS_VISIBLE | SB_I_NOEXEC | SB_I_NODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	s->s_flags |= SB_NODIRATIME | SB_NOSUID | SB_NOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	s->s_blocksize = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	s->s_blocksize_bits = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	s->s_magic = PROC_SUPER_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	s->s_op = &proc_sops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	s->s_time_gran = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	s->s_fs_info = fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	 * procfs isn't actually a stacking filesystem; however, there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	 * too much magic going on inside it to permit stacking things on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	 * top of it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	s->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	/* procfs dentries and inodes don't require IO to create */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	s->s_shrink.seeks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	pde_get(&proc_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	root_inode = proc_get_inode(s, &proc_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (!root_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		pr_err("proc_fill_super: get root inode failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	s->s_root = d_make_root(root_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (!s->s_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		pr_err("proc_fill_super: allocate dentry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	ret = proc_setup_self(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	return proc_setup_thread_self(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static int proc_reconfigure(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	struct super_block *sb = fc->root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	struct proc_fs_info *fs_info = proc_sb_info(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	sync_filesystem(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	proc_apply_options(fs_info, fc, current_user_ns());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int proc_get_tree(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	return get_tree_nodev(fc, proc_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static void proc_fs_context_free(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct proc_fs_context *ctx = fc->fs_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	put_pid_ns(ctx->pid_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static const struct fs_context_operations proc_fs_context_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	.free		= proc_fs_context_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	.parse_param	= proc_parse_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	.get_tree	= proc_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	.reconfigure	= proc_reconfigure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int proc_init_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	struct proc_fs_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	ctx = kzalloc(sizeof(struct proc_fs_context), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (!ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	ctx->pid_ns = get_pid_ns(task_active_pid_ns(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	put_user_ns(fc->user_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	fc->user_ns = get_user_ns(ctx->pid_ns->user_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	fc->fs_private = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	fc->ops = &proc_fs_context_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void proc_kill_sb(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	struct proc_fs_info *fs_info = proc_sb_info(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (!fs_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		kill_anon_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	dput(fs_info->proc_self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	dput(fs_info->proc_thread_self);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	kill_anon_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	put_pid_ns(fs_info->pid_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	kfree(fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static struct file_system_type proc_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	.name			= "proc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	.init_fs_context	= proc_init_fs_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	.parameters		= proc_fs_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	.kill_sb		= proc_kill_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	.fs_flags		= FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) void __init proc_root_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	proc_init_kmemcache();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	set_proc_pid_nlink();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	proc_self_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	proc_thread_self_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	proc_symlink("mounts", NULL, "self/mounts");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	proc_net_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	proc_mkdir("fs", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	proc_mkdir("driver", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	/* just give it a mountpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	proc_create_mount_point("openprom");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	proc_tty_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	proc_mkdir("bus", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	proc_sys_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	register_filesystem(&proc_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int proc_root_getattr(const struct path *path, struct kstat *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			     u32 request_mask, unsigned int query_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	generic_fillattr(d_inode(path->dentry), stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	stat->nlink = proc_root.nlink + nr_processes();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	if (!proc_pid_lookup(dentry, flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	return proc_lookup(dir, dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int proc_root_readdir(struct file *file, struct dir_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (ctx->pos < FIRST_PROCESS_ENTRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		int error = proc_readdir(file, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		if (unlikely(error <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		ctx->pos = FIRST_PROCESS_ENTRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return proc_pid_readdir(file, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  * The root /proc directory is special, as it has the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * <pid> directories. Thus we don't use the generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  * directory handling functions for that..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static const struct file_operations proc_root_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	.read		 = generic_read_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	.iterate_shared	 = proc_root_readdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	.llseek		= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)  * proc root can do almost nothing..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static const struct inode_operations proc_root_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	.lookup		= proc_root_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	.getattr	= proc_root_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  * This is the root "inode" in the /proc tree..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct proc_dir_entry proc_root = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	.low_ino	= PROC_ROOT_INO, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	.namelen	= 5, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	.mode		= S_IFDIR | S_IRUGO | S_IXUGO, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	.nlink		= 2, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	.refcnt		= REFCOUNT_INIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	.proc_iops	= &proc_root_inode_operations, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	.proc_dir_ops	= &proc_root_operations,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	.parent		= &proc_root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	.subdir		= RB_ROOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	.name		= "/proc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) };