Omar Sandoval
5161144c3a
block: fix use-after-free in sys_ioprio_get()
...
commit 8ba8682107ee2ca3347354e018865d8e1967c5f4 upstream.
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);
}
}
}
for (;;) {
/* ioprio_get(IOPRIO_WHO_PGRP, 0); */
syscall(SYS_ioprio_get, 2, 0);
}
return 0;
}
This gets us KASAN dumps like this:
[ 35.526914] ==================================================================
[ 35.530009] BUG: KASAN: out-of-bounds in get_task_ioprio+0x7b/0x90 at addr ffff880066f34e6c
[ 35.530009] Read of size 2 by task ioprio-gpf/363
[ 35.530009] =============================================================================
[ 35.530009] BUG blkdev_ioc (Not tainted): kasan: bad access detected
[ 35.530009] -----------------------------------------------------------------------------
[ 35.530009] Disabling lock debugging due to kernel taint
[ 35.530009] INFO: Allocated in create_task_io_context+0x2b/0x370 age=0 cpu=0 pid=360
[ 35.530009] ___slab_alloc+0x55d/0x5a0
[ 35.530009] __slab_alloc.isra.20+0x2b/0x40
[ 35.530009] kmem_cache_alloc_node+0x84/0x200
[ 35.530009] create_task_io_context+0x2b/0x370
[ 35.530009] get_task_io_context+0x92/0xb0
[ 35.530009] copy_process.part.8+0x5029/0x5660
[ 35.530009] _do_fork+0x155/0x7e0
[ 35.530009] SyS_clone+0x19/0x20
[ 35.530009] do_syscall_64+0x195/0x3a0
[ 35.530009] return_from_SYSCALL_64+0x0/0x6a
[ 35.530009] INFO: Freed in put_io_context+0xe7/0x120 age=0 cpu=0 pid=1060
[ 35.530009] __slab_free+0x27b/0x3d0
[ 35.530009] kmem_cache_free+0x1fb/0x220
[ 35.530009] put_io_context+0xe7/0x120
[ 35.530009] put_io_context_active+0x238/0x380
[ 35.530009] exit_io_context+0x66/0x80
[ 35.530009] do_exit+0x158e/0x2b90
[ 35.530009] do_group_exit+0xe5/0x2b0
[ 35.530009] SyS_exit_group+0x1d/0x20
[ 35.530009] entry_SYSCALL_64_fastpath+0x1a/0xa4
[ 35.530009] INFO: Slab 0xffffea00019bcd00 objects=20 used=4 fp=0xffff880066f34ff0 flags=0x1fffe0000004080
[ 35.530009] INFO: Object 0xffff880066f34e58 @offset=3672 fp=0x0000000000000001
[ 35.530009] ==================================================================
Fix it by grabbing the task lock while we poke at the io_context.
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-08-10 11:49:28 +02:00
..
2015-11-20 08:49:28 -07:00
2015-10-21 14:43:44 -06:00
2016-03-03 15:07:28 -08:00
2015-12-03 10:18:21 -05:00
2016-04-12 09:08:40 -07:00
2015-05-05 13:40:42 -06:00
2015-11-25 10:12:54 -07:00
2015-10-21 14:43:45 -06:00
2015-11-06 17:50:42 -08:00
2014-06-03 12:57:53 -07:00
2015-10-28 09:12:58 +09:00
2015-09-11 09:03:50 -06:00
2016-02-17 12:30:56 -08:00
2014-05-28 10:15:41 -06:00
2015-09-29 11:32:50 -06:00
2015-11-07 10:40:47 -07:00
2015-11-06 17:50:42 -08:00
2015-10-01 10:10:57 +02:00
2015-11-20 20:29:45 -07:00
2015-11-11 09:36:56 -07:00
2016-03-09 15:34:49 -08:00
2014-04-09 21:54:06 -06:00
2015-12-03 09:32:33 -08:00
2015-01-23 14:15:46 -07:00
2015-09-18 11:56:28 -04:00
2015-11-24 15:24:10 -07:00
2015-11-19 13:47:10 -08:00
2015-09-19 18:57:09 -07:00
2012-12-06 14:33:02 +01:00
2015-02-04 09:57:52 -07:00
2015-09-18 11:56:28 -04:00
2014-01-21 20:18:26 -08:00
2014-09-08 10:00:35 -06:00
2014-02-24 14:46:32 -08:00
2015-10-21 15:00:54 -06:00
2015-10-21 14:42:42 -06:00
2015-10-21 14:46:56 -06:00
2016-08-10 11:49:28 +02:00
2014-09-27 09:14:59 -06:00
2012-03-06 21:27:21 +01:00
2014-09-27 09:14:59 -06:00
2015-11-16 15:21:48 -07:00
2016-05-04 14:48:39 -07:00
2015-11-06 17:50:42 -08:00
2015-10-21 14:42:38 -06:00