crypto: use-after-free in alg_bind

From: Dmitry Vyukov
Date: Tue Dec 29 2015 - 15:19:50 EST


Hello,

On commit 8513342170278468bac126640a5d2d12ffbff106
+ crypto: algif_skcipher - Use new skcipher interface
+ crypto: algif_skcipher - Require setkey before accept(2)
+ crypto: af_alg - Disallow bind/setkey/... after accept(2)

The following program causes use-after-free in alg_bind and later
terminates kernel:

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

int fd;

void *thr(void *arg)
{
switch ((long)arg) {
case 0:
fd = syscall(SYS_socket, 0x26ul, 0x5ul, 0x0ul, 0, 0, 0);
case 1:
*(uint16_t*)0x20000000 = (uint16_t)0x26;
memcpy((void*)0x20000002,
"\x73\x6b\x63\x69\x70\x68\x65\x72\x00\x00\x00\x00\x00\x00", 14);
*(uint32_t*)0x20000010 = (uint32_t)0x2a;
*(uint32_t*)0x20000014 = (uint32_t)0x8;
memcpy((void*)0x20000018,
"\x65\x63\x62\x28\x61\x65\x73\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
64);
syscall(SYS_bind, fd, 0x20000000ul, 0x58ul, 0, 0, 0);
break;
case 2:
syscall(SYS_accept4, fd, 0, 0, 0x80000ul, 0, 0);
break;
}
return 0;
}

int main()
{
long i;
pthread_t th[6];

syscall(SYS_mmap, 0x20000000ul, 0x1000ul, 0x3ul, 0x32ul,
0xfffffffffffffffful, 0x0ul);
for (i = 0; i < 6; i++)
pthread_create(&th[i], 0, thr, (void*)(i%3));
usleep(10000);
return 0;
}


==================================================================
BUG: KASAN: use-after-free in __lock_acquire+0x39db/0x3ca0 at addr
ffff880033e94f60
Read of size 8 by task a.out/7532
=============================================================================
BUG kmalloc-2048 (Not tainted): kasan: bad access detected
-----------------------------------------------------------------------------

INFO: Allocated in sk_prot_alloc+0x1ed/0x340 age=1 cpu=1 pid=7532
[< inline >] kmalloc include/linux/slab.h:463
[< none >] sk_prot_alloc+0x1ed/0x340 net/core/sock.c:1354
[< none >] sk_alloc+0x3a/0x6b0 net/core/sock.c:1419
[< none >] alg_create+0x93/0x170 crypto/af_alg.c:370
[< none >] __sock_create+0x37c/0x640 net/socket.c:1162
[< inline >] sock_create net/socket.c:1202
[< inline >] SYSC_socket net/socket.c:1232
[< none >] SyS_socket+0xef/0x1b0 net/socket.c:1212

INFO: Freed in sk_destruct+0x3d7/0x490 age=1 cpu=0 pid=7531
[< none >] kfree+0x26a/0x290 mm/slub.c:3662
[< inline >] sk_prot_free net/core/sock.c:1391
[< none >] sk_destruct+0x3d7/0x490 net/core/sock.c:1467
[< none >] __sk_free+0x57/0x200 net/core/sock.c:1475
[< none >] sk_free+0x30/0x40 net/core/sock.c:1486
[< inline >] sock_put include/net/sock.h:1627
[< none >] af_alg_release+0x5b/0x70 crypto/af_alg.c:123
[< none >] sock_release+0x8d/0x1d0 net/socket.c:571
[< none >] sock_close+0x16/0x20 net/socket.c:1022
[< none >] __fput+0x233/0x780 fs/file_table.c:208
[< none >] ____fput+0x15/0x20 fs/file_table.c:244
[< none >] task_work_run+0x16b/0x200 kernel/task_work.c:115
[< inline >] tracehook_notify_resume include/linux/tracehook.h:191
[< none >] exit_to_usermode_loop+0x180/0x1a0
arch/x86/entry/common.c:251
[< inline >] prepare_exit_to_usermode arch/x86/entry/common.c:282
[< none >] syscall_return_slowpath+0x19f/0x210
arch/x86/entry/common.c:344
[< none >] int_ret_from_sys_call+0x25/0x9f
arch/x86/entry/entry_64.S:281

INFO: Slab 0xffffea0000cfa400 objects=13 used=8 fp=0xffff880033e94ec0
flags=0x1fffc0000004080
INFO: Object 0xffff880033e94ec0 @offset=20160 fp=0xffff880033e96c48
CPU: 1 PID: 7532 Comm: a.out Tainted: G B 4.4.0-rc7+ #181
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
00000000ffffffff ffff88006a49fa10 ffffffff8289d9dd ffff88003e805200
ffff880033e94ec0 ffff880033e90000 ffff88006a49fa40 ffffffff816c8e24
ffff88003e805200 ffffea0000cfa400 ffff880033e94ec0 ffffffff88b866e0

Call Trace:
[<ffffffff816d239e>] __asan_report_load8_noabort+0x3e/0x40
mm/kasan/report.c:295
[<ffffffff813ee5ab>] __lock_acquire+0x39db/0x3ca0 kernel/locking/lockdep.c:3092
[<ffffffff813f0acf>] lock_acquire+0x19f/0x3c0 kernel/locking/lockdep.c:3585
[< inline >] __raw_spin_lock_bh include/linux/spinlock_api_smp.h:137
[<ffffffff85c8de0f>] _raw_spin_lock_bh+0x3f/0x50 kernel/locking/spinlock.c:175
[< inline >] spin_lock_bh include/linux/spinlock.h:307
[<ffffffff84b654d8>] lock_sock_nested+0x48/0x120 net/core/sock.c:2434
[< inline >] lock_sock include/net/sock.h:1481
[<ffffffff827ddc1a>] alg_bind+0x1aa/0x3f0 crypto/af_alg.c:182
[<ffffffff84b5d84a>] SYSC_bind+0x1ea/0x250 net/socket.c:1376
[<ffffffff84b5ff74>] SyS_bind+0x24/0x30 net/socket.c:1362
==================================================================
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/