A slab-out-of-bounds bug was found by syzkaller when fuzzing linux kernel rds protocol.
==================================================================
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.