• Omar Sandoval's avatar
    block: fix use-after-free in sys_ioprio_get() · 8ba86821
    Omar Sandoval authored
    get_task_ioprio() accesses the task->io_context without holding the task
    lock and thus can race with exit_io_context(), leading to a
    use-after-free. The reproducer below hits this within a few seconds on
    my 4-core QEMU VM:
    
    #define _GNU_SOURCE
    #include <assert.h>
    #include <unistd.h>
    #include <sys/syscall.h>
    #include <sys/wait.h>
    
    int main(int argc, char **argv)
    {
    	pid_t pid, child;
    	long nproc, i;
    
    	/* ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)); */
    	syscall(SYS_ioprio_set, 1, 0, 0x6000);
    
    	nproc = sysconf(_SC_NPROCESSORS_ONLN);
    
    	for (i = 0; i < nproc; i++) {
    		pid = fork();
    		assert(pid != -1);
    		if (pid == 0) {
    			for (;;) {
    				pid = fork();
    				assert(pid != -1);
    				if (pid == 0) {
    					_exit(0);
    				} else {
    					child = wait(NULL);
    					assert(child == pid);
    				}
    			}
    		}
    
    		pid = fork();
    		assert(pid != -1);
    		if (pid == 0) {
    			for (;;) {
    				/* ioprio_get(IOPRIO_WHO_PGRP, 0); */
    				syscall(SYS_ioprio_get, 2, 0);
    			}...
    8ba86821
ioprio.c 5.11 KB