Skip to content

Commit

Permalink
proc: Remove the now unnecessary internal mount of proc
Browse files Browse the repository at this point in the history
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: Alistair Strachan <astrachan@google.com>
Fixes: e94591d ("proc: Convert proc_mount to use mount_ns.")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
  • Loading branch information
Eric W. Biederman committed Feb 28, 2020
1 parent 76313c7 commit 69879c0
Show file tree
Hide file tree
Showing 5 changed files with 0 additions and 58 deletions.
36 changes: 0 additions & 36 deletions fs/proc/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,39 +292,3 @@ struct proc_dir_entry proc_root = {
.subdir = RB_ROOT,
.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);
}
2 changes: 0 additions & 2 deletions include/linux/pid_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ struct pid_namespace {
unsigned int level;
struct pid_namespace *parent;
#ifdef CONFIG_PROC_FS
struct vfsmount *proc_mnt;
struct dentry *proc_self;
struct dentry *proc_thread_self;
#endif
Expand All @@ -42,7 +41,6 @@ struct pid_namespace {
#endif
struct user_namespace *user_ns;
struct ucounts *ucounts;
struct work_struct proc_work;
kgid_t pid_gid;
int hide_pid;
int reboot; /* group exit code if this pidns was rebooted */
Expand Down
5 changes: 0 additions & 5 deletions include/linux/proc_ns.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,11 @@ enum {

#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 void proc_free_inum(unsigned int inum);

#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)
{
*inum = 1;
Expand Down
8 changes: 0 additions & 8 deletions kernel/pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,6 @@ void free_pid(struct pid *pid)
/* Handle a fork failure of the first process */
WARN_ON(ns->child_reaper);
ns->pid_allocated = 0;
/* fall through */
case 0:
schedule_work(&ns->proc_work);
break;
}

Expand Down Expand Up @@ -247,11 +244,6 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *set_tid,
tmp = tmp->parent;
}

if (unlikely(is_child_reaper(pid))) {
if (pid_ns_prepare_proc(ns))
goto out_free;
}

get_pid_ns(ns);
refcount_set(&pid->count, 1);
for (type = 0; type < PIDTYPE_MAX; ++type)
Expand Down
7 changes: 0 additions & 7 deletions kernel/pid_namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,6 @@ static struct kmem_cache *create_pid_cachep(unsigned int level)
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)
{
return inc_ucount(ns, current_euid(), UCOUNT_PID_NAMESPACES);
Expand Down Expand Up @@ -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->ucounts = ucounts;
ns->pid_allocated = PIDNS_ADDING;
INIT_WORK(&ns->proc_work, proc_cleanup_work);

return ns;

Expand Down

0 comments on commit 69879c0

Please sign in to comment.