]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/fork.c
Merge tag 'v5.2' into next
[linux.git] / kernel / fork.c
index 75675b9bf6dfd36066336c384e007de312f54004..fe83343da24ba2c6c36761983ad974e72fcbbf52 100644 (file)
@@ -248,7 +248,11 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
        struct page *page = alloc_pages_node(node, THREADINFO_GFP,
                                             THREAD_SIZE_ORDER);
 
-       return page ? page_address(page) : NULL;
+       if (likely(page)) {
+               tsk->stack = page_address(page);
+               return tsk->stack;
+       }
+       return NULL;
 #endif
 }
 
@@ -1712,31 +1716,6 @@ const struct file_operations pidfd_fops = {
 #endif
 };
 
-/**
- * pidfd_create() - Create a new pid file descriptor.
- *
- * @pid:  struct pid that the pidfd will reference
- *
- * This creates a new pid file descriptor with the O_CLOEXEC flag set.
- *
- * Note, that this function can only be called after the fd table has
- * been unshared to avoid leaking the pidfd to the new process.
- *
- * Return: On success, a cloexec pidfd is returned.
- *         On error, a negative errno number will be returned.
- */
-static int pidfd_create(struct pid *pid)
-{
-       int fd;
-
-       fd = anon_inode_getfd("[pidfd]", &pidfd_fops, get_pid(pid),
-                             O_RDWR | O_CLOEXEC);
-       if (fd < 0)
-               put_pid(pid);
-
-       return fd;
-}
-
 static void __delayed_free_task(struct rcu_head *rhp)
 {
        struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
@@ -1774,6 +1753,7 @@ static __latent_entropy struct task_struct *copy_process(
        int pidfd = -1, retval;
        struct task_struct *p;
        struct multiprocess_signals delayed;
+       struct file *pidfile = NULL;
 
        /*
         * Don't allow sharing the root directory with processes in a different
@@ -1822,8 +1802,6 @@ static __latent_entropy struct task_struct *copy_process(
        }
 
        if (clone_flags & CLONE_PIDFD) {
-               int reserved;
-
                /*
                 * - CLONE_PARENT_SETTID is useless for pidfds and also
                 *   parent_tidptr is used to return pidfds.
@@ -1834,16 +1812,6 @@ static __latent_entropy struct task_struct *copy_process(
                if (clone_flags &
                    (CLONE_DETACHED | CLONE_PARENT_SETTID | CLONE_THREAD))
                        return ERR_PTR(-EINVAL);
-
-               /*
-                * Verify that parent_tidptr is sane so we can potentially
-                * reuse it later.
-                */
-               if (get_user(reserved, parent_tidptr))
-                       return ERR_PTR(-EFAULT);
-
-               if (reserved != 0)
-                       return ERR_PTR(-EINVAL);
        }
 
        /*
@@ -2058,11 +2026,21 @@ static __latent_entropy struct task_struct *copy_process(
         * if the fd table isn't shared).
         */
        if (clone_flags & CLONE_PIDFD) {
-               retval = pidfd_create(pid);
+               retval = get_unused_fd_flags(O_RDWR | O_CLOEXEC);
                if (retval < 0)
                        goto bad_fork_free_pid;
 
                pidfd = retval;
+
+               pidfile = anon_inode_getfile("[pidfd]", &pidfd_fops, pid,
+                                             O_RDWR | O_CLOEXEC);
+               if (IS_ERR(pidfile)) {
+                       put_unused_fd(pidfd);
+                       retval = PTR_ERR(pidfile);
+                       goto bad_fork_free_pid;
+               }
+               get_pid(pid);   /* held by pidfile now */
+
                retval = put_user(pidfd, parent_tidptr);
                if (retval)
                        goto bad_fork_put_pidfd;
@@ -2180,6 +2158,9 @@ static __latent_entropy struct task_struct *copy_process(
                goto bad_fork_cancel_cgroup;
        }
 
+       /* past the last point of failure */
+       if (pidfile)
+               fd_install(pidfd, pidfile);
 
        init_task_pid_links(p);
        if (likely(p->pid)) {
@@ -2246,8 +2227,10 @@ static __latent_entropy struct task_struct *copy_process(
 bad_fork_cgroup_threadgroup_change_end:
        cgroup_threadgroup_change_end(current);
 bad_fork_put_pidfd:
-       if (clone_flags & CLONE_PIDFD)
-               ksys_close(pidfd);
+       if (clone_flags & CLONE_PIDFD) {
+               fput(pidfile);
+               put_unused_fd(pidfd);
+       }
 bad_fork_free_pid:
        if (pid != &init_struct_pid)
                free_pid(pid);