forked from mirrors/linux
		
	proc: Convert proc_mount to use mount_ns.
Move the call of get_pid_ns, the call of proc_parse_options, and the setting of s_iflags into proc_fill_super so that mount_ns can be used. Convert proc_mount to call mount_ns and remove the now unnecessary code. Acked-by: Seth Forshee <seth.forshee@canonical.com> Reviewed-by: Djalal Harouni <tixxdz@gmail.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
		
							parent
							
								
									d91ee87d8d
								
							
						
					
					
						commit
						e94591d0d9
					
				
					 3 changed files with 13 additions and 51 deletions
				
			
		|  | @ -457,12 +457,17 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) | ||||||
| 	return inode; | 	return inode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int proc_fill_super(struct super_block *s) | int proc_fill_super(struct super_block *s, void *data, int silent) | ||||||
| { | { | ||||||
|  | 	struct pid_namespace *ns = get_pid_ns(s->s_fs_info); | ||||||
| 	struct inode *root_inode; | 	struct inode *root_inode; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	s->s_iflags |= SB_I_USERNS_VISIBLE; | 	if (!proc_parse_options(data, ns)) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	/* User space would break if executables appear on proc */ | ||||||
|  | 	s->s_iflags |= SB_I_USERNS_VISIBLE | SB_I_NOEXEC; | ||||||
| 	s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC; | 	s->s_flags |= MS_NODIRATIME | MS_NOSUID | MS_NOEXEC; | ||||||
| 	s->s_blocksize = 1024; | 	s->s_blocksize = 1024; | ||||||
| 	s->s_blocksize_bits = 10; | 	s->s_blocksize_bits = 10; | ||||||
|  |  | ||||||
|  | @ -212,7 +212,7 @@ extern const struct inode_operations proc_pid_link_inode_operations; | ||||||
| 
 | 
 | ||||||
| extern void proc_init_inodecache(void); | extern void proc_init_inodecache(void); | ||||||
| extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); | extern struct inode *proc_get_inode(struct super_block *, struct proc_dir_entry *); | ||||||
| extern int proc_fill_super(struct super_block *); | extern int proc_fill_super(struct super_block *, void *data, int flags); | ||||||
| extern void proc_entry_rundown(struct proc_dir_entry *); | extern void proc_entry_rundown(struct proc_dir_entry *); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -268,6 +268,7 @@ static inline void proc_tty_init(void) {} | ||||||
|  * root.c |  * root.c | ||||||
|  */ |  */ | ||||||
| extern struct proc_dir_entry proc_root; | extern struct proc_dir_entry proc_root; | ||||||
|  | extern int proc_parse_options(char *options, struct pid_namespace *pid); | ||||||
| 
 | 
 | ||||||
| extern void proc_self_init(void); | extern void proc_self_init(void); | ||||||
| extern int proc_remount(struct super_block *, int *, char *); | extern int proc_remount(struct super_block *, int *, char *); | ||||||
|  |  | ||||||
|  | @ -23,21 +23,6 @@ | ||||||
| 
 | 
 | ||||||
| #include "internal.h" | #include "internal.h" | ||||||
| 
 | 
 | ||||||
| static int proc_test_super(struct super_block *sb, void *data) |  | ||||||
| { |  | ||||||
| 	return sb->s_fs_info == data; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int proc_set_super(struct super_block *sb, void *data) |  | ||||||
| { |  | ||||||
| 	int err = set_anon_super(sb, NULL); |  | ||||||
| 	if (!err) { |  | ||||||
| 		struct pid_namespace *ns = (struct pid_namespace *)data; |  | ||||||
| 		sb->s_fs_info = get_pid_ns(ns); |  | ||||||
| 	} |  | ||||||
| 	return err; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| enum { | enum { | ||||||
| 	Opt_gid, Opt_hidepid, Opt_err, | 	Opt_gid, Opt_hidepid, Opt_err, | ||||||
| }; | }; | ||||||
|  | @ -48,7 +33,7 @@ static const match_table_t tokens = { | ||||||
| 	{Opt_err, NULL}, | 	{Opt_err, NULL}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static int proc_parse_options(char *options, struct pid_namespace *pid) | int proc_parse_options(char *options, struct pid_namespace *pid) | ||||||
| { | { | ||||||
| 	char *p; | 	char *p; | ||||||
| 	substring_t args[MAX_OPT_ARGS]; | 	substring_t args[MAX_OPT_ARGS]; | ||||||
|  | @ -100,45 +85,16 @@ int proc_remount(struct super_block *sb, int *flags, char *data) | ||||||
| static struct dentry *proc_mount(struct file_system_type *fs_type, | static struct dentry *proc_mount(struct file_system_type *fs_type, | ||||||
| 	int flags, const char *dev_name, void *data) | 	int flags, const char *dev_name, void *data) | ||||||
| { | { | ||||||
| 	int err; |  | ||||||
| 	struct super_block *sb; |  | ||||||
| 	struct pid_namespace *ns; | 	struct pid_namespace *ns; | ||||||
| 	char *options; |  | ||||||
| 
 | 
 | ||||||
| 	if (flags & MS_KERNMOUNT) { | 	if (flags & MS_KERNMOUNT) { | ||||||
| 		ns = (struct pid_namespace *)data; | 		ns = data; | ||||||
| 		options = NULL; | 		data = NULL; | ||||||
| 	} else { | 	} else { | ||||||
| 		ns = task_active_pid_ns(current); | 		ns = task_active_pid_ns(current); | ||||||
| 		options = data; |  | ||||||
| 
 |  | ||||||
| 		/* Does the mounter have privilege over the pid namespace? */ |  | ||||||
| 		if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN)) |  | ||||||
| 			return ERR_PTR(-EPERM); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns); | 	return mount_ns(fs_type, flags, data, ns, ns->user_ns, proc_fill_super); | ||||||
| 	if (IS_ERR(sb)) |  | ||||||
| 		return ERR_CAST(sb); |  | ||||||
| 
 |  | ||||||
| 	if (!proc_parse_options(options, ns)) { |  | ||||||
| 		deactivate_locked_super(sb); |  | ||||||
| 		return ERR_PTR(-EINVAL); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (!sb->s_root) { |  | ||||||
| 		err = proc_fill_super(sb); |  | ||||||
| 		if (err) { |  | ||||||
| 			deactivate_locked_super(sb); |  | ||||||
| 			return ERR_PTR(err); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		sb->s_flags |= MS_ACTIVE; |  | ||||||
| 		/* User space would break if executables appear on proc */ |  | ||||||
| 		sb->s_iflags |= SB_I_NOEXEC; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return dget(sb->s_root); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void proc_kill_sb(struct super_block *sb) | static void proc_kill_sb(struct super_block *sb) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Eric W. Biederman
						Eric W. Biederman