• Alexey Dobriyan's avatar
    proc: fix coredump vs read /proc/*/stat race · 8bb2ee19
    Alexey Dobriyan authored
    do_task_stat() accesses IP and SP of a task without bumping reference
    count of a stack (which became an entity with independent lifetime at
    some point).
    
    Steps to reproduce:
    
        #include <stdio.h>
        #include <sys/types.h>
        #include <sys/stat.h>
        #include <fcntl.h>
        #include <sys/time.h>
        #include <sys/resource.h>
        #include <unistd.h>
        #include <sys/wait.h>
    
        int main(void)
        {
        	setrlimit(RLIMIT_CORE, &(struct rlimit){});
    
        	while (1) {
        		char buf[64];
        		char buf2[4096];
        		pid_t pid;
        		int fd;
    
        		pid = fork();
        		if (pid == 0) {
        			*(volatile int *)0 = 0;
        		}
    
        		snprintf(buf, sizeof(buf), "/proc/%u/stat", pid);
        		fd = open(buf, O_RDONLY);
        		read(fd, buf2, sizeof(buf2));
        		close(fd);
    
        		waitpid(pid, NULL, 0);
        	}
        	return 0;
        }
    
        BUG: unable to handle kernel paging request at 0000000000003fd8
        IP: do_task_stat+0x8b4/0xaf0
        PGD 800000003d73e067 P4D 800000003d73e067 PUD 3d558067 PMD 0
        Oops: 0000 [#1] PREEMPT SMP PTI
        CPU: 0 PID: 1417 Comm: a.out Not tainted 4.15.0-rc8-dirty #2
        Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1.fc27 04/01/2014
        RIP: 0010:do_task_stat+0x8b4/0xaf0
        Call Trace:
         proc_single_show+0x43/0x70
         seq_read+0xe6/0x3b0
         __vfs_read+0x1e/0x120
         vfs_read+0x84/0x110
         SyS_read+0x3d/0xa0
         entry_SYSCALL_64_fastpath+0x13/0x6c
        RIP: 0033:0x7f4d7928cba0
        RSP: 002b:00007ffddb245158 EFLAGS: 00000246
        Code: 03 b7 a0 01 00 00 4c 8b 4c 24 70 4c 8b 44 24 78 4c 89 74 24 18 e9 91 f9 ff ff f6 45 4d 02 0f 84 fd f7 ff ff 48 8b 45 40 48 89 ef <48> 8b 80 d8 3f 00 00 48 89 44 24 20 e8 9b 97 eb ff 48 89 44 24
        RIP: do_task_stat+0x8b4/0xaf0 RSP: ffffc90000607cc8
        CR2: 0000000000003fd8
    
    John Ogness said: for my tests I added an else case to verify that the
    race is hit and correctly mitigated.
    
    Link: http://lkml.kernel.org/r/20180116175054.GA11513@avx2Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
    Reported-by: default avatar"Kohli, Gaurav" <gkohli@codeaurora.org>
    Tested-by: default avatarJohn Ogness <john.ogness@linutronix.de>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Ingo Molnar <mingo@elte.hu>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    8bb2ee19
array.c 20.3 KB