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
@ -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 New Issue
Block a user