Merge branch 'for-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
[platform/kernel/linux-rpi.git] / kernel / fork.c
index ba122d6..d2a967b 100644 (file)
@@ -2176,16 +2176,15 @@ static __latent_entropy struct task_struct *copy_process(
        INIT_LIST_HEAD(&p->thread_group);
        p->task_works = NULL;
 
-       cgroup_threadgroup_change_begin(current);
        /*
         * Ensure that the cgroup subsystem policies allow the new process to be
         * forked. It should be noted the the new process's css_set can be changed
         * between here and cgroup_post_fork() if an organisation operation is in
         * progress.
         */
-       retval = cgroup_can_fork(p);
+       retval = cgroup_can_fork(p, args);
        if (retval)
-               goto bad_fork_cgroup_threadgroup_change_end;
+               goto bad_fork_put_pidfd;
 
        /*
         * From this point on we must avoid any synchronous user-space
@@ -2290,8 +2289,7 @@ static __latent_entropy struct task_struct *copy_process(
        write_unlock_irq(&tasklist_lock);
 
        proc_fork_connector(p);
-       cgroup_post_fork(p);
-       cgroup_threadgroup_change_end(current);
+       cgroup_post_fork(p, args);
        perf_event_fork(p);
 
        trace_task_newtask(p, clone_flags);
@@ -2302,9 +2300,7 @@ static __latent_entropy struct task_struct *copy_process(
 bad_fork_cancel_cgroup:
        spin_unlock(&current->sighand->siglock);
        write_unlock_irq(&tasklist_lock);
-       cgroup_cancel_fork(p);
-bad_fork_cgroup_threadgroup_change_end:
-       cgroup_threadgroup_change_end(current);
+       cgroup_cancel_fork(p, args);
 bad_fork_put_pidfd:
        if (clone_flags & CLONE_PIDFD) {
                fput(pidfile);
@@ -2633,6 +2629,9 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
                     !valid_signal(args.exit_signal)))
                return -EINVAL;
 
+       if ((args.flags & CLONE_INTO_CGROUP) && args.cgroup < 0)
+               return -EINVAL;
+
        *kargs = (struct kernel_clone_args){
                .flags          = args.flags,
                .pidfd          = u64_to_user_ptr(args.pidfd),
@@ -2643,6 +2642,7 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
                .stack_size     = args.stack_size,
                .tls            = args.tls,
                .set_tid_size   = args.set_tid_size,
+               .cgroup         = args.cgroup,
        };
 
        if (args.set_tid &&
@@ -2686,7 +2686,8 @@ static inline bool clone3_stack_valid(struct kernel_clone_args *kargs)
 static bool clone3_args_valid(struct kernel_clone_args *kargs)
 {
        /* Verify that no unknown flags are passed along. */
-       if (kargs->flags & ~(CLONE_LEGACY_FLAGS | CLONE_CLEAR_SIGHAND))
+       if (kargs->flags &
+           ~(CLONE_LEGACY_FLAGS | CLONE_CLEAR_SIGHAND | CLONE_INTO_CGROUP))
                return false;
 
        /*