Re: KASAN: slab-out-of-bounds Write in sha3_update (2)
From: Eric Biggers <hidden>
Date: 2017-12-22 17:22:45
Also in:
keyrings, lkml
[+Cc keyrings@vger.kernel.org] On Fri, Dec 22, 2017 at 07:55:01AM -0800, syzbot wrote:
Hello, syzkaller hit the following crash on 9035a8961b504d0997369509ab8c6b1f0a4ee33d git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/master compiler: gcc (GCC) 7.1.1 20170620 .config is attached Raw console output is attached. C reproducer is attached syzkaller reproducer is attached. See https://goo.gl/kgGztJ for information about syzkaller reproducers audit: type=1400 audit(1513919078.260:7): avc: denied { map } for pid=3152 comm="syzkaller717822" path="/root/syzkaller717822551" dev="sda1" ino=16481 scontext=unconfined_u:system_r:insmod_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=1 ================================================================== BUG: KASAN: slab-out-of-bounds in memcpy include/linux/string.h:344 [inline] BUG: KASAN: slab-out-of-bounds in sha3_update+0xdf/0x2e0 crypto/sha3_generic.c:161 Write of size 192 at addr ffff8801cf0e3b3c by task syzkaller717822/3152 CPU: 0 PID: 3152 Comm: syzkaller717822 Not tainted 4.15.0-rc4+ #232 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:17 [inline] dump_stack+0x194/0x257 lib/dump_stack.c:53 print_address_description+0x73/0x250 mm/kasan/report.c:252 kasan_report_error mm/kasan/report.c:351 [inline] kasan_report+0x25b/0x340 mm/kasan/report.c:409 check_memory_region_inline mm/kasan/kasan.c:260 [inline] check_memory_region+0x137/0x190 mm/kasan/kasan.c:267 memcpy+0x37/0x50 mm/kasan/kasan.c:303 memcpy include/linux/string.h:344 [inline] sha3_update+0xdf/0x2e0 crypto/sha3_generic.c:161 crypto_shash_update+0xda/0x240 crypto/shash.c:110 hmac_update+0x7e/0xa0 crypto/hmac.c:122 crypto_shash_update+0xda/0x240 crypto/shash.c:110 kdf_ctr security/keys/dh.c:181 [inline] keyctl_dh_compute_kdf security/keys/dh.c:226 [inline] __keyctl_dh_compute+0x160f/0x1990 security/keys/dh.c:398 keyctl_dh_compute+0xac/0xf3 security/keys/dh.c:434 SYSC_keyctl security/keys/keyctl.c:1741 [inline] SyS_keyctl+0x72/0x2c0 security/keys/keyctl.c:1637 entry_SYSCALL_64_fastpath+0x1f/0x96 RIP: 0033:0x43feb9 RSP: 002b:00007ffd3aef51a8 EFLAGS: 00000217 ORIG_RAX: 00000000000000fa RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 000000000043feb9 RDX: 0000000020c2cfff RSI: 00000000204c8ff4 RDI: 0000000000000017 RBP: 00000000006ca018 R08: 00000000208e6fd4 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000217 R12: 0000000000401820 R13: 00000000004018b0 R14: 0000000000000000 R15: 0000000000000000 Allocated by task 3152: save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_kmalloc+0xad/0xe0 mm/kasan/kasan.c:551 __do_kmalloc mm/slab.c:3708 [inline] __kmalloc+0x162/0x760 mm/slab.c:3717 kmalloc include/linux/slab.h:504 [inline] kdf_alloc security/keys/dh.c:111 [inline] __keyctl_dh_compute+0x2b0/0x1990 security/keys/dh.c:288 keyctl_dh_compute+0xac/0xf3 security/keys/dh.c:434 SYSC_keyctl security/keys/keyctl.c:1741 [inline] SyS_keyctl+0x72/0x2c0 security/keys/keyctl.c:1637 entry_SYSCALL_64_fastpath+0x1f/0x96 Freed by task 1637: save_stack+0x43/0xd0 mm/kasan/kasan.c:447 set_track mm/kasan/kasan.c:459 [inline] kasan_slab_free+0x71/0xc0 mm/kasan/kasan.c:524 __cache_free mm/slab.c:3488 [inline] kfree+0xd6/0x260 mm/slab.c:3803 kernfs_fop_release+0x13f/0x180 fs/kernfs/file.c:783 __fput+0x327/0x7e0 fs/file_table.c:210 ____fput+0x15/0x20 fs/file_table.c:244 task_work_run+0x199/0x270 kernel/task_work.c:113 tracehook_notify_resume include/linux/tracehook.h:191 [inline] exit_to_usermode_loop+0x296/0x310 arch/x86/entry/common.c:162 prepare_exit_to_usermode arch/x86/entry/common.c:195 [inline] syscall_return_slowpath+0x490/0x550 arch/x86/entry/common.c:264 entry_SYSCALL_64_fastpath+0x94/0x96
The problem is that KEYCTL_DH_COMPUTE allows the user to request and use any hash algorithm as an unkeyed hash without checking whether it is in fact unkeyed. We could fix this by checking for !crypto_shash_alg_has_setkey() after allocating the hash, but now I'd really like to solve this for all users by having crypto_[as]hash_init() and crypto_[as]hash_digest() automatically return -ENOKEY if a key is needed and one hasn't been set. That would also have solved the bug I fixed specifically for HMAC by "crypto: hmac - require that the underlying hash algorithm is unkeyed". Eric