Omar Sandoval
8ba8682107
block: fix use-after-free in sys_ioprio_get()
...
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.
Cc: stable@vger.kernel.org
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Omar Sandoval <osandov@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
2016-07-01 08:39:24 -06:00
..
2016-05-20 17:58:30 -07:00
2016-01-09 08:39:04 -08:00
2015-12-09 08:04:29 -07:00
2016-05-05 13:03:29 -06:00
2016-02-09 12:33:35 -07:00
2016-04-13 13:33:19 -06:00
2015-05-05 13:40:42 -06:00
2016-04-13 13:33:19 -06:00
2015-10-21 14:43:45 -06:00
2015-11-06 17:50:42 -08:00
2016-06-07 10:47:48 -06:00
2016-04-08 19:46:28 -04:00
2016-03-03 14:42:49 -07:00
2014-05-28 10:15:41 -06:00
2015-12-03 09:56:27 -07:00
2016-03-20 09:34:02 -06:00
2016-04-12 15:07:36 -06:00
2015-10-01 10:10:57 +02:00
2016-06-02 11:47:32 -06:00
2016-02-09 12:42:17 -07:00
2016-04-13 13:33:19 -06:00
2014-04-09 21:54:06 -06:00
2016-04-12 15:46:27 -06:00
2015-01-23 14:15:46 -07:00
2016-05-10 08:41:37 -06:00
2015-12-22 09:38:34 -07:00
2015-12-22 09:38:16 -07: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
2016-04-04 10:41:08 -07:00
2014-01-21 20:18:26 -08:00
2016-04-04 10:41:08 -07:00
2016-02-01 09:09:55 -07:00
2015-10-21 15:00:54 -06:00
2016-01-19 15:03:34 -08:00
2016-05-26 19:34:26 -07:00
2016-07-01 08:39:24 -06:00
2016-02-27 10:28:52 -08:00
2012-03-06 21:27:21 +01:00
2016-01-23 18:45:06 -08:00
2015-11-16 15:21:48 -07:00
2016-04-15 15:44:10 -07:00
2015-11-06 17:50:42 -08:00
2015-10-21 14:42:38 -06:00