Commit 69879c01 authored by Eric W. Biederman's avatar Eric W. Biederman

proc: Remove the now unnecessary internal mount of proc

There remains no more code in the kernel using pids_ns->proc_mnt,
therefore remove it from the kernel.

The big benefit of this change is that one of the most error prone and
tricky parts of the pid namespace implementation, maintaining kernel
mounts of proc is removed.

In addition removing the unnecessary complexity of the kernel mount
fixes a regression that caused the proc mount options to be ignored.
Now that the initial mount of proc comes from userspace, those mount
options are again honored.  This fixes Android's usage of the proc
hidepid option.
Reported-by: default avatarAlistair Strachan <astrachan@google.com>
Fixes: e94591d0 ("proc: Convert proc_mount to use mount_ns.")
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent 76313c70
...@@ -292,39 +292,3 @@ struct proc_dir_entry proc_root = { ...@@ -292,39 +292,3 @@ struct proc_dir_entry proc_root = {
.subdir = RB_ROOT, .subdir = RB_ROOT,
.name = "/proc", .name = "/proc",
}; };
int pid_ns_prepare_proc(struct pid_namespace *ns)
{
struct proc_fs_context *ctx;
struct fs_context *fc;
struct vfsmount *mnt;
fc = fs_context_for_mount(&proc_fs_type, SB_KERNMOUNT);
if (IS_ERR(fc))
return PTR_ERR(fc);
if (fc->user_ns != ns->user_ns) {
put_user_ns(fc->user_ns);
fc->user_ns = get_user_ns(ns->user_ns);
}
ctx = fc->fs_private;
if (ctx->pid_ns != ns) {
put_pid_ns(ctx->pid_ns);
get_pid_ns(ns);
ctx->pid_ns = ns;
}
mnt = fc_mount(fc);
put_fs_context(fc);
if (IS_ERR(mnt))
return PTR_ERR(mnt);
ns->proc_mnt = mnt;
return 0;
}
void pid_ns_release_proc(struct pid_namespace *ns)
{
kern_unmount(ns->proc_mnt);
}
...@@ -33,7 +33,6 @@ struct pid_namespace { ...@@ -33,7 +33,6 @@ struct pid_namespace {
unsigned int level; unsigned int level;
struct pid_namespace *parent; struct pid_namespace *parent;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct vfsmount *proc_mnt;
struct dentry *proc_self; struct dentry *proc_self;
struct dentry *proc_thread_self; struct dentry *proc_thread_self;
#endif #endif
...@@ -42,7 +41,6 @@ struct pid_namespace { ...@@ -42,7 +41,6 @@ struct pid_namespace {
#endif #endif
struct user_namespace *user_ns; struct user_namespace *user_ns;
struct ucounts *ucounts; struct ucounts *ucounts;
struct work_struct proc_work;
kgid_t pid_gid; kgid_t pid_gid;
int hide_pid; int hide_pid;
int reboot; /* group exit code if this pidns was rebooted */ int reboot; /* group exit code if this pidns was rebooted */
......
...@@ -50,16 +50,11 @@ enum { ...@@ -50,16 +50,11 @@ enum {
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
extern int pid_ns_prepare_proc(struct pid_namespace *ns);
extern void pid_ns_release_proc(struct pid_namespace *ns);
extern int proc_alloc_inum(unsigned int *pino); extern int proc_alloc_inum(unsigned int *pino);
extern void proc_free_inum(unsigned int inum); extern void proc_free_inum(unsigned int inum);
#else /* CONFIG_PROC_FS */ #else /* CONFIG_PROC_FS */
static inline int pid_ns_prepare_proc(struct pid_namespace *ns) { return 0; }
static inline void pid_ns_release_proc(struct pid_namespace *ns) {}
static inline int proc_alloc_inum(unsigned int *inum) static inline int proc_alloc_inum(unsigned int *inum)
{ {
*inum = 1; *inum = 1;
......
...@@ -144,9 +144,6 @@ void free_pid(struct pid *pid) ...@@ -144,9 +144,6 @@ void free_pid(struct pid *pid)
/* Handle a fork failure of the first process */ /* Handle a fork failure of the first process */
WARN_ON(ns->child_reaper); WARN_ON(ns->child_reaper);
ns->pid_allocated = 0; ns->pid_allocated = 0;
/* fall through */
case 0:
schedule_work(&ns->proc_work);
break; break;
} }
...@@ -247,11 +244,6 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *set_tid, ...@@ -247,11 +244,6 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *set_tid,
tmp = tmp->parent; tmp = tmp->parent;
} }
if (unlikely(is_child_reaper(pid))) {
if (pid_ns_prepare_proc(ns))
goto out_free;
}
get_pid_ns(ns); get_pid_ns(ns);
refcount_set(&pid->count, 1); refcount_set(&pid->count, 1);
for (type = 0; type < PIDTYPE_MAX; ++type) for (type = 0; type < PIDTYPE_MAX; ++type)
......
...@@ -57,12 +57,6 @@ static struct kmem_cache *create_pid_cachep(unsigned int level) ...@@ -57,12 +57,6 @@ static struct kmem_cache *create_pid_cachep(unsigned int level)
return READ_ONCE(*pkc); return READ_ONCE(*pkc);
} }
static void proc_cleanup_work(struct work_struct *work)
{
struct pid_namespace *ns = container_of(work, struct pid_namespace, proc_work);
pid_ns_release_proc(ns);
}
static struct ucounts *inc_pid_namespaces(struct user_namespace *ns) static struct ucounts *inc_pid_namespaces(struct user_namespace *ns)
{ {
return inc_ucount(ns, current_euid(), UCOUNT_PID_NAMESPACES); return inc_ucount(ns, current_euid(), UCOUNT_PID_NAMESPACES);
...@@ -114,7 +108,6 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns ...@@ -114,7 +108,6 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns
ns->user_ns = get_user_ns(user_ns); ns->user_ns = get_user_ns(user_ns);
ns->ucounts = ucounts; ns->ucounts = ucounts;
ns->pid_allocated = PIDNS_ADDING; ns->pid_allocated = PIDNS_ADDING;
INIT_WORK(&ns->proc_work, proc_cleanup_work);
return ns; return ns;
......
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