RDS: slab-out-of-bounds Read in rds_rdma_extra_size

67 views
Skip to first unread message

GeneBlue

unread,
Feb 27, 2018, 2:21:27 AM2/27/18
to santosh....@oracle.com, David S. Miller, net...@vger.kernel.org, linux...@vger.kernel.org, rds-...@oss.oracle.com, syzkaller
Hi:
  A slab-out-of-bounds bug was found by syzkaller when fuzzing linux kernel rds protocol.
kernel info:
version: Linux 4.12-rc7
commit: c0bc126f97fb929b3ae02c1c62322645d70eb408

==================================================================
BUG: KASAN: slab-out-of-bounds in rds_rdma_extra_size+0x268/0x280 net/rds/rdma.c:529
Read of size 8 at addr ffff88003abd98d0 by task syzkaller129800/2745

CPU: 0 PID: 2745 Comm: syzkaller129800 Not tainted 4.12.0-rc7+ #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:16 [inline]
 dump_stack+0xb3/0x117 lib/dump_stack.c:52
 print_address_description+0x73/0x290 mm/kasan/report.c:252
 kasan_report_error mm/kasan/report.c:351 [inline]
 kasan_report+0x22f/0x340 mm/kasan/report.c:408
 __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:429
 rds_rdma_extra_size+0x268/0x280 net/rds/rdma.c:529
 rds_rm_size net/rds/send.c:885 [inline]
 rds_sendmsg+0xe28/0x2020 net/rds/send.c:1080
 sock_sendmsg_nosec net/socket.c:633 [inline]
 sock_sendmsg+0xcc/0x110 net/socket.c:643
 ___sys_sendmsg+0x7df/0x940 net/socket.c:1997
 __sys_sendmsg+0xce/0x170 net/socket.c:2031
 SYSC_sendmsg net/socket.c:2042 [inline]
 SyS_sendmsg+0x2d/0x50 net/socket.c:2038
 entry_SYSCALL_64_fastpath+0x1f/0xbe
RIP: 0033:0x435079
RSP: 002b:00007ffdf1b63498 EFLAGS: 00000217 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00000000004002b0 RCX: 0000000000435079
RDX: 0000000000000000 RSI: 0000000020039fc8 RDI: 0000000000000003
RBP: 0000000000000046 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000217 R12: 0000000000000000
R13: 00000000004019f0 R14: 0000000000401a80 R15: 0000000000000000

Allocated by task 2745:
 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
 save_stack+0x46/0xd0 mm/kasan/kasan.c:513
 set_track mm/kasan/kasan.c:525 [inline]
 kasan_kmalloc+0xab/0xe0 mm/kasan/kasan.c:617
 __kmalloc+0x126/0x300 mm/slub.c:3745
 kmalloc include/linux/slab.h:497 [inline]
 sock_kmalloc+0x80/0xc0 net/core/sock.c:1901
 ___sys_sendmsg+0x501/0x940 net/socket.c:1964
 __sys_sendmsg+0xce/0x170 net/socket.c:2031
 SYSC_sendmsg net/socket.c:2042 [inline]
 SyS_sendmsg+0x2d/0x50 net/socket.c:2038
 entry_SYSCALL_64_fastpath+0x1f/0xbe

Freed by task 2387:
 save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:59
 save_stack+0x46/0xd0 mm/kasan/kasan.c:513
 set_track mm/kasan/kasan.c:525 [inline]
 kasan_slab_free+0x73/0xc0 mm/kasan/kasan.c:590
 slab_free_hook mm/slub.c:1357 [inline]
 slab_free_freelist_hook mm/slub.c:1379 [inline]
 slab_free mm/slub.c:2961 [inline]
 kfree+0xf4/0x2e0 mm/slub.c:3882
 free_rb_tree_fname+0x81/0xe0 fs/ext4/dir.c:402
 ext4_htree_free_dir_info fs/ext4/dir.c:424 [inline]
 ext4_release_dir+0x44/0x60 fs/ext4/dir.c:622
 __fput+0x29d/0x720 fs/file_table.c:209
 ____fput+0x15/0x20 fs/file_table.c:245
 task_work_run+0xf8/0x170 kernel/task_work.c:116
 tracehook_notify_resume include/linux/tracehook.h:191 [inline]
 exit_to_usermode_loop+0x147/0x170 arch/x86/entry/common.c:161
 prepare_exit_to_usermode arch/x86/entry/common.c:194 [inline]
 syscall_return_slowpath+0x18f/0x1d0 arch/x86/entry/common.c:263
 entry_SYSCALL_64_fastpath+0xbc/0xbe

The buggy address belongs to the object at ffff88003abd98a0
 which belongs to the cache kmalloc-64 of size 64
The buggy address is located 48 bytes inside of
 64-byte region [ffff88003abd98a0, ffff88003abd98e0)
The buggy address belongs to the page:
page:ffffea0000eaf640 count:1 mapcount:0 mapping:          (null) index:0xffff88003abd9b40
flags: 0x100000000000100(slab)
raw: 0100000000000100 0000000000000000 ffff88003abd9b40 00000001802a0026
raw: 0000000000000000 0000000100000001 ffff88003e803800 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88003abd9780: fb fb fb fb fb fb fb fb fc fc fc fc fb fb fb fb
 ffff88003abd9800: fb fb fb fb fc fc fc fc fb fb fb fb fb fb fb fb
>ffff88003abd9880: fc fc fc fc 00 00 00 00 00 00 fc fc fc fc fc fc
                                                 ^
 ffff88003abd9900: fb fb fb fb fb fb fb fb fc fc fc fc 00 00 00 00
 ffff88003abd9980: 00 00 00 00 fc fc fc fc fb fb fb fb fb fb fb fb
==================================================================


Syzkaller reproducer:
# {Threaded:false Collide:false Repeat:false Procs:1 Sandbox: Fault:false FaultCall:-1 FaultNth:0 EnableTun:false UseTmpDir:false HandleSegv:false WaitRepeat:false Debug:false Repro:false}
mmap(&(0x7f0000000000/0x42000)=nil, 0x42000, 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = socket$rds(0x15, 0x5, 0x0)
bind$rds(r0, &(0x7f0000031000-0x10)={0x2, 0xffffffffffffffff, @loopback=0x7f000001, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x10)
sendmsg$rds(r0, &(0x7f000003a000-0x38)={&(0x7f0000001000-0x10)={0x2, 0xffffffffffffffff, @rand_addr=0x3, [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x10, &(0x7f0000030000)=[{&(0x7f0000040000)=""/23, 0x0}, {&(0x7f0000026000-0x8b)=""/139, 0x0}, {&(0x7f0000042000-0xa9)=""/169, 0x1cc}, {&(0x7f000001e000)=""/138, 0x0}, {&(0x7f000003a000)=""/52, 0x0}, {&(0x7f0000041000)=""/42, 0x0}, {&(0x7f0000027000)=""/97, 0x0}], 0x0, &(0x7f000003c000)=[@rdma_args={0x27, 0x114, 0x1, {{0x0, 0x0}, {&(0x7f000003d000-0xc5)=""/197, 0xc5}, &(0x7f000003d000-0x90)=[], 0x2, 0x3, 0x0}}], 0x30, 0x0}, 0x0)


C reproducer:
// autogenerated by syzkaller (http://github.com/google/syzkaller)

#define _GNU_SOURCE 
#include <endian.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>

long r[1];
void loop()
{
	memset(r, -1, sizeof(r));
	syscall(__NR_mmap, 0x20000000, 0x42000, 3, 0x32, -1, 0);
	r[0] = syscall(__NR_socket, 0x15, 5, 0);
*(uint16_t*)0x20030ff0 = 2;
*(uint16_t*)0x20030ff2 = 0;
*(uint32_t*)0x20030ff4 = htobe32(0x7f000001);
*(uint8_t*)0x20030ff8 = 0;
*(uint8_t*)0x20030ff9 = 0;
*(uint8_t*)0x20030ffa = 0;
*(uint8_t*)0x20030ffb = 0;
*(uint8_t*)0x20030ffc = 0;
*(uint8_t*)0x20030ffd = 0;
*(uint8_t*)0x20030ffe = 0;
*(uint8_t*)0x20030fff = 0;
	syscall(__NR_bind, r[0], 0x20030ff0, 0x10);
*(uint64_t*)0x20039fc8 = 0x20000ff0;
*(uint32_t*)0x20039fd0 = 0x10;
*(uint64_t*)0x20039fd8 = 0x20030000;
*(uint64_t*)0x20039fe0 = 0;
*(uint64_t*)0x20039fe8 = 0x2003c000;
*(uint64_t*)0x20039ff0 = 0x30;
*(uint32_t*)0x20039ff8 = 0;
*(uint16_t*)0x20000ff0 = 2;
*(uint16_t*)0x20000ff2 = 0;
*(uint32_t*)0x20000ff4 = htobe32(3);
*(uint8_t*)0x20000ff8 = 0;
*(uint8_t*)0x20000ff9 = 0;
*(uint8_t*)0x20000ffa = 0;
*(uint8_t*)0x20000ffb = 0;
*(uint8_t*)0x20000ffc = 0;
*(uint8_t*)0x20000ffd = 0;
*(uint8_t*)0x20000ffe = 0;
*(uint8_t*)0x20000fff = 0;
*(uint64_t*)0x20030000 = 0x20040000;
*(uint64_t*)0x20030008 = 0;
*(uint64_t*)0x20030010 = 0x20025f75;
*(uint64_t*)0x20030018 = 0;
*(uint64_t*)0x20030020 = 0x20041f57;
*(uint64_t*)0x20030028 = 0x1cc;
*(uint64_t*)0x20030030 = 0x2001e000;
*(uint64_t*)0x20030038 = 0;
*(uint64_t*)0x20030040 = 0x2003a000;
*(uint64_t*)0x20030048 = 0;
*(uint64_t*)0x20030050 = 0x20041000;
*(uint64_t*)0x20030058 = 0;
*(uint64_t*)0x20030060 = 0x20027000;
*(uint64_t*)0x20030068 = 0;
*(uint64_t*)0x2003c000 = 0x27;
*(uint32_t*)0x2003c008 = 0x114;
*(uint32_t*)0x2003c00c = 1;
*(uint32_t*)0x2003c010 = 0;
*(uint32_t*)0x2003c014 = 0;
*(uint64_t*)0x2003c018 = 0x2003cf3b;
*(uint64_t*)0x2003c020 = 0xc5;
*(uint64_t*)0x2003c028 = 0x2003cf70;
*(uint64_t*)0x2003c030 = 2;
*(uint64_t*)0x2003c038 = 3;
*(uint64_t*)0x2003c040 = 0;
	syscall(__NR_sendmsg, r[0], 0x20039fc8, 0);
}

int main()
{
	loop();
	return 0;
}
*********************************************************************************************************

And the kernel config file is attached.
config
Reply all
Reply to author
Forward
0 new messages