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; | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| 	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_blocksize = 1024; | ||||
| 	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 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 *); | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -268,6 +268,7 @@ static inline void proc_tty_init(void) {} | |||
|  * root.c | ||||
|  */ | ||||
| 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 int proc_remount(struct super_block *, int *, char *); | ||||
|  |  | |||
|  | @ -23,21 +23,6 @@ | |||
| 
 | ||||
| #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 { | ||||
| 	Opt_gid, Opt_hidepid, Opt_err, | ||||
| }; | ||||
|  | @ -48,7 +33,7 @@ static const match_table_t tokens = { | |||
| 	{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; | ||||
| 	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, | ||||
| 	int flags, const char *dev_name, void *data) | ||||
| { | ||||
| 	int err; | ||||
| 	struct super_block *sb; | ||||
| 	struct pid_namespace *ns; | ||||
| 	char *options; | ||||
| 
 | ||||
| 	if (flags & MS_KERNMOUNT) { | ||||
| 		ns = (struct pid_namespace *)data; | ||||
| 		options = NULL; | ||||
| 		ns = data; | ||||
| 		data = NULL; | ||||
| 	} else { | ||||
| 		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); | ||||
| 	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); | ||||
| 	return mount_ns(fs_type, flags, data, ns, ns->user_ns, proc_fill_super); | ||||
| } | ||||
| 
 | ||||
| static void proc_kill_sb(struct super_block *sb) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Eric W. Biederman
						Eric W. Biederman