Skip to content
  • Eugene Syromiatnikov's avatar
    fork: block invalid exit signals with clone3() · a0eb9abd
    Eugene Syromiatnikov authored
    Previously, higher 32 bits of exit_signal fields were lost when copied
    to the kernel args structure (that uses int as a type for the respective
    field). Moreover, as Oleg has noted, exit_signal is used unchecked, so
    it has to be checked for sanity before use; for the legacy syscalls,
    applying CSIGNAL mask guarantees that it is at least non-negative;
    however, there's no such thing is done in clone3() code path, and that
    can break at least thread_group_leader.
    
    This commit adds a check to copy_clone_args_from_user() to verify that
    the exit signal is limited by CSIGNAL as with legacy clone() and that
    the signal is valid. With this we don't get the legacy clone behavior
    were an invalid signal could be handed down and would only be detected
    and ignored in do_notify_parent(). Users of clone3() will now get a
    proper error when they pass an invalid exit signal. Note, that this is
    not user-visible behavior since no kernel with clone3() has been
    released yet.
    
    The following program will cause a splat on a non-fixed clone3() version
    and will fail correctly on a fixed version:
    
     #define _GNU_SOURCE
     #include <linux/sched.h>
     #include <linux/types.h>
     #include <sched.h>
     #include <stdio.h>
     #include <stdlib.h>
     #include <sys/syscall.h>
     #include <sys/wait.h>
     #include <unistd.h>
    
     int main(int argc, char *argv[])
     {
            pid_t pid = -1;
            struct clone_args args = {0};
            args.exit_signal = -1;
    
            pid = syscall(__NR_clone3, &args, sizeof(struct clone_args));
            if (pid < 0)
                    exit(EXIT_FAILURE);
    
            if (pid == 0)
                    exit(EXIT_SUCCESS);
    
            wait(NULL);
    
            exit(EXIT_SUCCESS);
     }
    
    Fixes: 7f192e3c
    
     ("fork: add clone3")
    Reported-by: default avatarOleg Nesterov <oleg@redhat.com>
    Suggested-by: default avatarOleg Nesterov <oleg@redhat.com>
    Suggested-by: default avatarDmitry V. Levin <ldv@altlinux.org>
    Signed-off-by: default avatarEugene Syromiatnikov <esyr@redhat.com>
    Link: https://lore.kernel.org/r/4b38fa4ce420b119a4c6345f42fe3cec2de9b0b5.1568223594.git.esyr@redhat.com
    
    
    [christian.brauner@ubuntu.com: simplify check and rework commit message]
    Signed-off-by: default avatarChristian Brauner <christian.brauner@ubuntu.com>
    a0eb9abd