Use-after-free in ppoll

Dmitry Vyukov
2015-11-22T14:14:55Z

Hello,

On commit f2d10565b9bdbb722bd43e6e1a759eeddb9645c8 (Nov 20).

The following program triggers use-after-free:

// autogenerated by syzkaller (http://github.com/google/syzkaller)
#include <syscall.h>
#include <string.h>
#include <stdint.h>
#include <pthread.h>

void *thread(void *p)
{
syscall(SYS_write, (long)p, 0x2000278ful, 0x1ul, 0, 0, 0);
return 0;
}

int main()
{
long r0 = syscall(SYS_mmap, 0x20000000ul, 0x10000ul, 0x2ul,
0x32ul, 0xfffffffffffffffful, 0x0ul);
long r1 = syscall(SYS_socketpair, 0x1ul, 0x3ul, 0x0ul,
0x20001000ul, 0, 0);
long r2 = -1;
if (r1 != -1)
r2 = *(uint32_t*)0x20001000;
long r3 = -1;
if (r1 != -1)
r3 = *(uint32_t*)0x20001004;
//long r4 = syscall(SYS_getuid, 0, 0, 0, 0, 0, 0);
long r5 = syscall(SYS_close, r2, 0, 0, 0, 0, 0);
pthread_t th;
pthread_create(&th, 0, thread, (void*)(long)r3);
long r6 = syscall(SYS_clock_gettime, 0x0ul, 0x20000ff0ul, 0, 0, 0, 0);
long r7 = -1;
if (r6 != -1)
r7 = *(uint64_t*)0x20000ff0;
long r8 = -1;
if (r6 != -1)
r8 = *(uint64_t*)0x20000ff8;
*(uint32_t*)0x20000fff = r3;
*(uint16_t*)0x20001003 = 0x8;
*(uint16_t*)0x20001005 = 0x9;
*(uint32_t*)0x20001007 = r3;
*(uint16_t*)0x2000100b = 0x6;
*(uint16_t*)0x2000100d = 0x22b;
*(uint32_t*)0x2000100f = r3;
*(uint16_t*)0x20001013 = 0xe7838d7e9fc50196;
*(uint16_t*)0x20001015 = 0x9c2;
*(uint64_t*)0x20000ffc = 0;//r7;
*(uint64_t*)0x20001004 = /*r8+*/10000000;
*(uint64_t*)0x20000ffd = 0x3;
long r21 = syscall(SYS_ppoll, 0x20000ffful, 0x3ul,
0x20000ffcul, 0x20000ffdul, 0x8ul, 0);
return 0;
}

[ 2672.994366] BUG: KASAN: use-after-free in
do_raw_spin_lock+0x22/0x220 at addr ffff88003d8829c4
[ 2672.994366] Read of size 4 by task syzkaller_execu/6653
[ 2672.994366] =============================================================================
[ 2672.994366] BUG UNIX (Not tainted): kasan: bad access detected
[ 2672.994366] -----------------------------------------------------------------------------
[ 2672.994366]
[ 2672.994366] INFO: Allocated in sk_prot_alloc+0x53/0x220 age=11 cpu=1 pid=6653
[ 2672.994366] __slab_alloc+0x235/0x570
[ 2672.994366] kmem_cache_alloc+0x131/0x170
[ 2672.994366] sk_prot_alloc+0x53/0x220
[ 2672.994366] sk_alloc+0x38/0x1c0
[ 2672.994366] unix_create1+0x5a/0x260
[ 2672.994366] unix_create+0xc4/0x110
[ 2672.994366] __sock_create+0x31c/0x490
[ 2672.994366] SyS_socketpair+0x14c/0x3c0
[ 2672.994366] entry_SYSCALL_64_fastpath+0x31/0x9a

[ 2672.994366] INFO: Freed in sk_destruct+0x1b5/0x260 age=12 cpu=1 pid=6653
[ 2672.994366] __slab_free+0x1ec/0x350
[ 2672.994366] kmem_cache_free+0x1ed/0x200
[ 2672.994366] sk_destruct+0x1b5/0x260
[ 2672.994366] __sk_free+0x61/0x110
[ 2672.994366] sk_free+0x30/0x40
[ 2672.994366] unix_dgram_poll+0x352/0x390
[ 2672.994366] sock_poll+0x13b/0x340
[ 2672.994366] do_sys_poll+0x405/0x860
[ 2672.994366] SyS_ppoll+0x1a9/0x310
[ 2672.994366] entry_SYSCALL_64_fastpath+0x31/0x9a
[ 2672.994366] INFO: Slab 0xffffea0000f62000 objects=17 used=5
fp=0xffff88003d882440 flags=0x100000000004080
[ 2672.994366] INFO: Object 0xffff88003d882440 @offset=9280
fp=0xffff88003d880e80
[ 2672.994366]
[ 2672.994366] CPU: 1 PID: 6653 Comm: syzkaller_execu Tainted: G B
4.4.0-rc1+ #66
[ 2672.994366] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS Bochs 01/01/2011
[ 2672.994366] ffffea0000f62000 ffff88004cee76f0 ffffffff8165b3b7
ffff88003e28fa80
[ 2672.994366] ffff88003d882440 ffff88003d880000 ffff88004cee7720
ffffffff812c32c4
[ 2672.994366] ffff88003e28fa80 ffffea0000f62000 ffff88003d882440
ffff88003d8829c0
[ 2672.994366] Call Trace:
[ 2672.994366] [<ffffffff812ca0fa>] __asan_load4+0x6a/0x70
[ 2672.994366] [<ffffffff81126832>] do_raw_spin_lock+0x22/0x220
[ 2672.994366] [<ffffffff821d6061>] _raw_spin_lock_irqsave+0x51/0x60
[ 2672.994366] [<ffffffff8110d748>] remove_wait_queue+0x18/0x80
[ 2672.994366] [<ffffffff812fddab>] poll_freewait+0x7b/0x130
[ 2672.994366] [<ffffffff8130063c>] do_sys_poll+0x4dc/0x860
[ 2672.994366] [<ffffffff81300eb9>] SyS_ppoll+0x1a9/0x310
[ 2672.994366] ==================================================================

[ 40.882065] BUG: KASAN: use-after-free in
__lock_acquire+0x7ea/0x2600 at addr ffff88006d145f98
[ 40.882065] Read of size 8 by task a.out/13880
[ 40.882065] =============================================================================
[ 40.887431] BUG UNIX (Not tainted): kasan: bad access detected
[ 40.887431] -----------------------------------------------------------------------------
[ 40.887431]
[ 40.887431] INFO: Allocated in sk_prot_alloc+0x53/0x220 age=0 cpu=3 pid=13885
[ 40.887431] ___slab_alloc+0x489/0x4e0
[ 40.896414] __slab_alloc+0x4c/0x90
[ 40.896786] kmem_cache_alloc+0x131/0x170
[ 40.896786] sk_prot_alloc+0x53/0x220
[ 40.896786] sk_alloc+0x38/0x1c0
[ 40.896786] unix_create1+0x5a/0x260
[ 40.896786] unix_create+0xc4/0x110
[ 40.896786] __sock_create+0x31c/0x490
[ 40.896786] SyS_socketpair+0x101/0x3c0
[ 40.896786] entry_SYSCALL_64_fastpath+0x31/0x9a

[ 40.896786] INFO: Freed in sk_destruct+0x1b5/0x260 age=0 cpu=1 pid=13888
[ 40.896786] __slab_free+0x1ec/0x350
[ 40.896786] kmem_cache_free+0x1ed/0x200
[ 40.896786] sk_destruct+0x1b5/0x260
[ 40.896786] __sk_free+0x61/0x110
[ 40.896786] sk_free+0x30/0x40
[ 40.896786] unix_release_sock+0x320/0x4e0
[ 40.896786] unix_release+0x35/0x60
[ 40.896786] sock_release+0x4e/0x100
[ 40.896786] sock_close+0x16/0x20
[ 40.896786] __fput+0x173/0x360
[ 40.896786] ____fput+0x15/0x20
[ 40.896786] task_work_run+0xe1/0x110
[ 40.896786] do_exit+0x55f/0x1690
[ 40.896786] do_group_exit+0xa7/0x190
[ 40.896786] get_signal+0x3d7/0xd80
[ 40.896786] do_signal+0x8c/0xa60
[ 40.896786] INFO: Slab 0xffffea0001b45000 objects=17 used=1
fp=0xffff88006d140000 flags=0x500000000004080
[ 40.896786] INFO: Object 0xffff88006d145a00 @offset=23040
fp=0xffff88006d144380
[ 40.896786]
[ 40.896786] Call Trace:
[ 40.896786] [<ffffffff812ca2b4>] __asan_load8+0x64/0x70
[ 40.896786] [<ffffffff8111db0a>] __lock_acquire+0x7ea/0x2600
[ 40.896786] [<ffffffff81120d51>] lock_acquire+0x101/0x1d0
[ 40.896786] [<ffffffff821d6e49>] _raw_spin_lock_irqsave+0x49/0x60
[ 40.896786] [<ffffffff8110d748>] remove_wait_queue+0x18/0x80
[ 40.896786] [<ffffffff812fde8b>] poll_freewait+0x7b/0x130
[ 40.896786] [<ffffffff8130071c>] do_sys_poll+0x4dc/0x860
[ 40.896786] [<ffffffff81300f99>] SyS_ppoll+0x1a9/0x310
[ 40.896786] ==================================================================

[ 198.125032] BUG: KASAN: use-after-free in
__lock_acquire+0x7ea/0x2600 at addr ffff88006d271c18
[ 198.125032] Read of size 8 by task executor/12267
[ 198.125032] =============================================================================
[ 198.125032] BUG UNIX (Not tainted): kasan: bad access detected
[ 198.125032] -----------------------------------------------------------------------------
[ 198.125032]
[ 198.136373] INFO: Allocated in sk_prot_alloc+0x53/0x220 age=27
cpu=3 pid=12267
[ 198.136373] __slab_alloc+0x235/0x570
[ 198.136373] kmem_cache_alloc+0x131/0x170
[ 198.136373] sk_prot_alloc+0x53/0x220
[ 198.136373] sk_alloc+0x38/0x1c0
[ 198.136373] unix_create1+0x5a/0x260
[ 198.136373] unix_create+0xc4/0x110
[ 198.136373] __sock_create+0x31c/0x490
[ 198.136373] SyS_socketpair+0x14c/0x3c0
[ 198.136373] entry_SYSCALL_64_fastpath+0x31/0x9a

[ 198.136373] INFO: Freed in sk_destruct+0x1b5/0x260 age=25 cpu=1 pid=12268
[ 198.136373] __slab_free+0x1ec/0x350
[ 198.136373] kmem_cache_free+0x1ed/0x200
[ 198.136373] sk_destruct+0x1b5/0x260
[ 198.136373] __sk_free+0x61/0x110
[ 198.136373] sk_free+0x30/0x40
[ 198.136373] unix_dgram_sendmsg+0x9f4/0xa50
[ 198.136373] sock_sendmsg+0x84/0xa0
[ 198.136373] sock_write_iter+0x142/0x1f0
[ 198.136373] __vfs_write+0x249/0x2a0
[ 198.136373] vfs_write+0x113/0x290
[ 198.136373] SyS_write+0xbb/0x170
[ 198.136373] entry_SYSCALL_64_fastpath+0x31/0x9a
[ 198.136373] INFO: Slab 0xffffea0001b49c00 objects=17 used=6
fp=0xffff88006d272580 flags=0x500000000004080
[ 198.136373] INFO: Object 0xffff88006d271680 @offset=5760
fp=0xffff88006d275280
[ 198.136373] CPU: 3 PID: 12267 Comm: executor Tainted: G B
4.4.0-rc1+ #66
[ 198.136373] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS Bochs 01/01/2011
[ 198.247087] ffffea0001b49c00 ffff88006cb9f540 ffffffff8165b3b7
ffff88003d98aac0
[ 198.247087] ffff88006d271680 ffff88006d270000 ffff88006cb9f570
ffffffff812c32c4
[ 198.247087] ffff88003d98aac0 ffffea0001b49c00 ffff88006d271680
0000000000000000
[ 198.247087] Call Trace:

[ 198.247087] [<ffffffff812ca1d4>] __asan_load8+0x64/0x70
[ 198.247087] [<ffffffff8111db0a>] __lock_acquire+0x7ea/0x2600
[ 198.247087] [<ffffffff81120d51>] lock_acquire+0x101/0x1d0
[ 198.247087] [<ffffffff821d6059>] _raw_spin_lock_irqsave+0x49/0x60
[ 198.247087] [<ffffffff8110d748>] remove_wait_queue+0x18/0x80
[ 198.247087] [<ffffffff812fddab>] poll_freewait+0x7b/0x130
[ 198.247087] [<ffffffff8130063c>] do_sys_poll+0x4dc/0x860
[ 198.247087] [<ffffffff81300eb9>] SyS_ppoll+0x1a9/0x310
[ 198.247087] ==================================================================

This can be related to "Use-after-free in ep_remove_wait_queue":
https://groups.google.com/d/msg/syzkaller/3twDUI4Cpm8/EY6qWbrjCAAJ
However, stacks are somewhat different, so maybe it is a different
issue (or at least another test case).

Thank you