scsi: memory leak in sg_start_req

From: Dmitry Vyukov
Date: Tue Jan 09 2018 - 11:05:51 EST


Hello,

syzkaller has found the following memory leak:

unreferenced object 0xffff88004c190000 (size 8328):
comm "syz-executor", pid 4627, jiffies 4294749150 (age 45.507s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20 00 00 00 22 01 00 00 00 00 00 00 04 00 00 00 ..."...........
backtrace:
[<000000005955b5a9>] kmalloc_order+0x59/0x80 mm/slab_common.c:1124
[<0000000043ae006e>] kmalloc_order_trace+0x1f/0x160 mm/slab_common.c:1133
[<00000000d33b2e16>] kmalloc_large include/linux/slab.h:433 [inline]
[<00000000d33b2e16>] __kmalloc+0x2c4/0x340 mm/slub.c:3751
[<00000000e7430040>] kmalloc include/linux/slab.h:504 [inline]
[<00000000e7430040>] bio_alloc_bioset+0x4d5/0x7e0 block/bio.c:450
[<00000000f370e717>] bio_kmalloc include/linux/bio.h:410 [inline]
[<00000000f370e717>] bio_copy_user_iov+0x2be/0xcb0 block/bio.c:1226
[<000000001d0b79ed>] __blk_rq_map_user_iov block/blk-map.c:67 [inline]
[<000000001d0b79ed>] blk_rq_map_user_iov+0x2b6/0x7d0 block/blk-map.c:136
[<000000004200a869>] blk_rq_map_user+0x11e/0x170 block/blk-map.c:166
[<000000008f21739e>] sg_start_req drivers/scsi/sg.c:1794 [inline]
[<000000008f21739e>] sg_common_write.isra.16+0x14df/0x1ed0
drivers/scsi/sg.c:777
[<00000000093f61e3>] sg_write+0x8a7/0xd7b drivers/scsi/sg.c:677
[<00000000b67dafdc>] __vfs_write+0x10d/0x8f0 fs/read_write.c:480
[<000000000638f16f>] vfs_write+0x1fd/0x570 fs/read_write.c:544
[<000000006a7e6867>] SYSC_write fs/read_write.c:589 [inline]
[<000000006a7e6867>] SyS_write+0xfa/0x250 fs/read_write.c:581

can be reproduced with the following program:

// autogenerated by syzkaller (http://github.com/google/syzkaller)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
int fd = open("/dev/sg1", O_RDWR);
const char *data =
"\xb6\x3d\xb8\x5e\x1e\x8d\x22\x00\x00\x00\x00\x00\x00\x08\xaf\xd6\x1d"
"\xcc\x43\x6a\xed\x5e\xd2\xbc\x70\x18\xce\xbc\x9b\x97\xae\x21\x91\x4d"
"\x87\x2c\x67\x8c\xe2\x2c\x9b\x16\x0e\x96\xaa\x1f\xae\x1a";
write(fd, data, 0x30);
return 0;
}

if executed in a loop, memory consumption grows infinitely.

on upstream commit b2cd1df66037e7c4697c7e40496bf7e4a5e16a2d