proc: Remove the now unnecessary internal mount of proc
authorEric W. Biederman <ebiederm@xmission.com>
Thu, 20 Feb 2020 14:08:20 +0000 (08:08 -0600)
committerEric W. Biederman <ebiederm@xmission.com>
Fri, 28 Feb 2020 18:06:14 +0000 (12:06 -0600)
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: e94591d0d90c ("proc: Convert proc_mount to use mount_ns.")
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
fs/proc/root.c
include/linux/pid_namespace.h
include/linux/proc_ns.h
kernel/pid.c
kernel/pid_namespace.c

index 608233dfd29cf2ea59989f36a5b06441c7517e4e..2633f10446c3befc0710775a78fa340cb7224889 100644 (file)
@@ -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);
-}
index 2ed6af88794b0bf9adffdcf861cf9f0358305630..4956e362e55e69e07d0fefd477aab34c37b68bc1 100644 (file)
@@ -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
@@ -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 */
index 4626b1ac3b6c2c35bb64fba657f244d533fa9ce0..e1106a077c1a62dc50264f73a37e396957fb34d1 100644 (file)
@@ -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;
index ca08d6a3aa77f21e1cfa23af4a8895f601a974b0..60820e72634c8c10cf2c969e7922b8afd4910cd1 100644 (file)
@@ -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;
                }
 
@@ -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)
index d40017e79ebe505174693bdeeb936f442ee66938..318fcc6ba301dfb771cfa6e2683100615fc117bd 100644 (file)
@@ -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);
@@ -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;