Commit e94591d0 authored by Eric W. Biederman's avatar Eric W. Biederman

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: default avatarSeth Forshee <seth.forshee@canonical.com>
Reviewed-by: default avatarDjalal Harouni <tixxdz@gmail.com>
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent d91ee87d
...@@ -457,12 +457,17 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) ...@@ -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; ...@@ -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) {} ...@@ -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 @@ ...@@ -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 = { ...@@ -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) ...@@ -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);
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) static void proc_kill_sb(struct super_block *sb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment