All of lore.kernel.org
 help / color / mirror / Atom feed
* sound: out-of-bounds write in snd_rawmidi_kernel_write1
@ 2016-02-03  8:57 ` Dmitry Vyukov
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry Vyukov @ 2016-02-03  8:57 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai, alsa-devel, LKML
  Cc: syzkaller, Kostya Serebryany, Alexander Potapenko, Sasha Levin

Hello,

The following program triggers an out-of-bounds write in
snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
copy -1 bytes (aka 4GB) from user space into kernel smashing all on
its way.

==================================================================
BUG: KASAN: use-after-free in memset+0x1a/0x30 at addr ffff8800326e3cef
Write of size 4294950912 by task a.out/7292
=============================================================================
BUG kmalloc-4096 (Not tainted): kasan: bad access detected
-----------------------------------------------------------------------------

INFO: Allocated in open_substream+0x2ff/0x780 age=288 cpu=1 pid=7287
[<      none      >] ___slab_alloc+0x564/0x5b0 mm/slub.c:2470
[<      none      >] __slab_alloc+0x66/0xc0 mm/slub.c:2499
[<     inline     >] slab_alloc_node mm/slub.c:2562
[<     inline     >] slab_alloc mm/slub.c:2604
[<      none      >] kmem_cache_alloc_trace+0x25c/0x300 mm/slub.c:2621
[<     inline     >] kmalloc include/linux/slab.h:463
[<     inline     >] snd_rawmidi_runtime_create sound/core/rawmidi.c:127
[<      none      >] open_substream+0x2ff/0x780 sound/core/rawmidi.c:266
[<      none      >] rawmidi_open_priv+0x144/0x300 sound/core/rawmidi.c:312
[<      none      >] snd_rawmidi_open+0x3fb/0xa90 sound/core/rawmidi.c:416
[<      none      >] soundcore_open+0x30f/0x640 sound/sound_core.c:639
[<      none      >] chrdev_open+0x22a/0x4c0 fs/char_dev.c:388
[<      none      >] do_dentry_open+0x6a2/0xcb0 fs/open.c:736
[<      none      >] vfs_open+0x17b/0x1f0 fs/open.c:853
[<     inline     >] do_last fs/namei.c:3254
[<      none      >] path_openat+0xde9/0x5e30 fs/namei.c:3386
[<      none      >] do_filp_open+0x18e/0x250 fs/namei.c:3421
[<      none      >] do_sys_open+0x1fc/0x420 fs/open.c:1022
[<     inline     >] SYSC_open fs/open.c:1040
[<      none      >] SyS_open+0x2d/0x40 fs/open.c:1035
[<      none      >] entry_SYSCALL_64_fastpath+0x16/0x7a
arch/x86/entry/entry_64.S:185

Call Trace:
 [<ffffffff817654b7>] __asan_storeN+0x127/0x1a0 mm/kasan/kasan.c:522
 [<ffffffff8176582a>] memset+0x1a/0x30 mm/kasan/kasan.c:280
 [<ffffffff82c15294>] copy_user_handle_tail+0xb4/0xd0
arch/x86/lib/usercopy_64.c:86
 [<     inline     >] copy_from_user ./arch/x86/include/asm/uaccess.h:735
 [<ffffffff852855da>] snd_rawmidi_kernel_write1+0x34a/0x760
sound/core/rawmidi.c:1250
 [<ffffffff852878b3>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1318
 [<ffffffff817b8be1>] do_loop_readv_writev+0x141/0x1e0 fs/read_write.c:719
 [<ffffffff817bcb38>] do_readv_writev+0x5f8/0x6e0 fs/read_write.c:849
 [<ffffffff817bcd56>] vfs_writev+0x86/0xc0 fs/read_write.c:886
 [<     inline     >] SYSC_writev fs/read_write.c:919
 [<ffffffff817bfec1>] SyS_writev+0x111/0x2b0 fs/read_write.c:911
 [<ffffffff86661376>] entry_SYSCALL_64_fastpath+0x16/0x7a
arch/x86/entry/entry_64.S:185
==================================================================

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

long r[19];

int main()
{
  memset(r, -1, sizeof(r));
  r[0] = syscall(SYS_mmap, 0x20000000ul, 0x22000ul, 0x3ul, 0x32ul,
                 0xfffffffffffffffful, 0x0ul);
  r[2] = syscall(SYS_open, "/dev/midi3", 0x2ul, 0, 0, 0);
  *(uint64_t*)0x20013ffe = (uint64_t)0x20013f69;
  *(uint64_t*)0x20014006 = (uint64_t)0x97;
  *(uint64_t*)0x2001400e = (uint64_t)0x20003ffe;
  *(uint64_t*)0x20014016 = (uint64_t)0x3;
  *(uint64_t*)0x2001401e = (uint64_t)0x2001ef70;
  *(uint64_t*)0x20014026 = (uint64_t)0x92;
  *(uint64_t*)0x2001402e = (uint64_t)0x20014730;
  *(uint64_t*)0x20014036 = (uint64_t)0x1;
  *(uint64_t*)0x2001403e = (uint64_t)0x2001e000;
  *(uint64_t*)0x20014046 = (uint64_t)0x1000;
  memcpy((void*)0x20013f69,
         "\x0e\x6f\xfe\xa4\xc8\xbf\xaa\x28\x69\x82\xe0\x8c\x45\xab\x90"
         "\xb9\x6a\xeb\x50\x3d\x1a\x59\x59\x33\x0a\xa5\xb8\xfe\x83\x75"
         "\x1f\xb5\x25\x76\x65\x53\xb6\xe7\xe2\xe7\xe3\xd7\x55\x36\xb6"
         "\x59\x2f\xf8\x61\xda\xdb\x73\x32\x94\xb1\x0e\x17\x87\xad\x8f"
         "\x73\x6c\xc7\xeb\x47\xa2\x65\x77\xfb\xfc\xec\x70\x5c\x9e\x01"
         "\x78\xef\x1b\x69\xab\xef\x58\x13\x35\x99\xf0\x2b\x25\x99\xdb"
         "\xba\x16\xa7\x43\xc5\x19\x32\x91\x13\x24\x15\xd1\x5e\xb0\x1a"
         "\x5f\x63\xe2\xc3\x61\x9a\x79\x82\x57\x60\x21\x79\x6e\xf5\x21"
         "\x74\x18\xcf\x8f\x73\x93\x70\x3a\xfe\xf8\xe3\xde\x6a\x85\x3b"
         "\x5a\xfc\x0b\xfe\x02\x8f\x32\xe6\xc5\x14\x1c\x07\x24\xce\xcb"
         "\x95",
         151);
  memcpy((void*)0x20003ffe, "\x3d\x07\x31", 3);
  memcpy((void*)0x2001ef70,
         "\x5c\x39\xe0\x3f\xe7\xdd\x08\xeb\x7c\xb0\xe7\x31\x09\xdf\x84"
         "\x1a\xbb\x98\xe1\xc8\x08\x00\x3b\xe9\xef\x62\x4a\x18\x10\xff"
         "\xa1\x7f\xa0\xd6\x81\x86\xed\xb5\x43\x33\x7c\xa6\x01\xb8\xfc"
         "\xe1\xee\x43\x95\x05\xf1\x5d\xa6\xb4\xb1\x62\x74\x82\xc6\x8b"
         "\x9f\xfb\x9b\xe8\x41\xee\x2e\x44\xc0\x20\x37\xca\xe5\x33\xf3"
         "\xeb\x9e\x2e\x15\x56\xce\x26\x5e\x6c\xee\xca\x49\x00\xe6\xf2"
         "\x21\xd4\x07\xf1\x00\xee\x21\x5a\xd5\x7a\x84\x4c\x3e\x7c\x8d"
         "\xe5\xb5\x35\x57\x69\xe4\x18\x09\x5b\xa7\xdb\xe6\x2f\x56\x78"
         "\x83\xa1\x0c\xdd\x07\x74\x32\xb2\x85\x75\xeb\x51\x5b\x22\xd1"
         "\x57\x95\xcd\xc2\xc4\xf9\x2e\xd8\xce\x9a\x52",
         146);
  memcpy((void*)0x20014730, "\xc3", 1);
  memcpy(
      (void*)0x2001e000,
      "\xff\x20\xcc\xa3\x99\x07\x76\x17\xc4\x29\xef\xa5\x6a\xef\x9c\x9b"
      "\x58\x94\x16\xfc\x87\x60\xb1\x04\x16\x80\x1d\xcb\xfd\x8b\xd7\x9a"
      "\x41\x87\xb2\xdf\xe8\xc3\x17\x50\xd6\x5a\x01\x06\xc7\xc5\xb1\xf3"
      "\x56\x57\x81\xa8\x2c\x0b\x81\x67\x93\x59\xc1\xbb\xb5\x2d\x45\xc5"
      "\x27\x05\x66\x0b\xfd\x28\x1e\xdb\x45\x89\x34\x0b\x03\xfe\x5f\xa7"
      "\x47\xeb\xa1\xe0\xff\xe1\xdb\x12\xa7\x11\x37\xe0\x96\x53\xa2\x29"
      "\x1d\x3c\x3c\xda\x8e\x97\xeb\x58\x64\x8d\xff\x13\x70\x08\x96\x28"
      "\x32\x4e\xce\x4c\xb3\x17\x1c\x74\xa8\x8d\x7b\x78\x32\x4b\xcc\xf8"
      "\xf7\xcb\x33\x5c\xd5\x6b\xa3\x2a\x9c\x7c\x41\x3e\x87\x92\xec\x22"
      "\x44\x36\x28\x2d\x76\xde\x44\xa8\xef\x9d\x2c\xa2\xf2\xc5\x94\x2b"
      "\x3a\x17\xa4\xd7\x82\x4e\xef\xee\x1a\x4a\x6b\x98\xd5\xe4\x40\xbc"
      "\x5a\xe1\x76\x47\x17\x2b\x45\xb6\xb6\xa4\xeb\x5a\x54\x82\x6a\x98"
      "\x14\xf0\x4e\x5a\x8c\x30\x6a\x0f\xcb\x0f\x1b\x62\x8c\x48\x54\x16"
      "\xb8\x94\x28\xd0\xcc\x47\x4f\xb4\x01\x40\x3c\xb7\xed\xf0\x96\x2a"
      "\x55\xb2\xac\xf6\xa2\xab\x93\x19\x3f\xf6\xf8\xad\x8f\xa3\x5a\x6f"
      "\x15\x26\xa3\x25\xbb\x58\x6e\x02\x58\xfa\x3a\xcf\xd9\xf8\x17\xb9"
      "\xa1\x4c\x45\x16\x45\xcb\x7a\x84\x37\x3a\xb4\x3a\xc6\x98\xa9\x5c"
      "\xf4\x9e\xdb\xcf\xa9\xbb\xcc\xcb\x15\x36\x52\xb0\xcc\x3d\xd0\xfa"
      "\xd6\xc0\xff\xf6\xb7\x0e\x80\x31\x8e\x76\xfc\xe9\xd8\xf6\xb4\xbc"
      "\xfa\xec\x94\x13\x64\x9d\x13\x7e\x91\x9c\x10\x27\xda\xc8\xea\x9b"
      "\xc2\x09\x58\x81\x9e\x44\xf2\xc3\xef\x94\x6d\x2f\xa9\xa5\x19\xd7"
      "\x78\x61\x2e\xd3\x01\x8a\xc3\xac\x1b\xb9\xaa\x00\x12\xc5\x7e\x7f"
      "\x7b\x34\x27\x4c\x38\x00\x9c\x57\xa6\xe2\x5a\x5a\xe6\x00\x01\x56"
      "\xa2\xed\xa6\xcd\x95\x0b\xde\x5e\x09\x62\x61\x7c\x2b\x16\x13\xb4"
      "\x04\xf8\x1a\x5b\x15\x9d\x62\xd5\xac\x4b\x5b\x35\x70\xd0\xe2\x26"
      "\xf9\xc0\x7c\x73\xad\x9c\xd5\xef\x7b\x9f\x01\x8b\xb6\xb3\x85\xbf"
      "\x34\xa2\x8c\xce\x8a\xaf\xe1\x5b\xdd\x7f\xa6\x23\x55\x8b\xa4\xa3"
      "\x06\x2f\xf1\xa0\xd8\x2a\xcc\x9a\x94\x19\x22\xfe\x65\x69\x9b\xcb"
      "\x6d\x6c\x1c\x38\x25\x82\x9b\xec\xe1\x75\xb4\xbe\xac\x21\x4b\xec"
      "\xfd\x22\x76\xcb\x35\x4b\xaa\x5c\x3a\x7b\xaa\x6f\x3c\x68\xa7\xa5"
      "\x3d\xa2\xd5\x25\x9a\xe4\x6f\x80\xc5\xb5\xcf\x76\x37\xd8\xd9\x25"
      "\xe6\xc7\x26\x40\xdf\x1d\xd3\x41\xb2\x58\x69\xa7\x18\x57\xf8\x35"
      "\x26\x70\x30\x08\x76\xed\x2b\x37\x2a\x54\x7d\xa5\x7a\x66\x8d\xbf"
      "\x4a\x20\x3d\x1b\xd1\x28\x1e\x7e\xfe\xd3\xb1\x6c\x64\x87\x70\x27"
      "\x9e\xcf\x07\xd9\x5a\x9e\xbb\xdb\x3b\xb2\xcb\x50\x78\x3c\x45\x76"
      "\xec\x59\xa9\xca\xb2\x80\x8c\xc5\x62\x76\x8c\x76\x61\xb5\xf2\xcf"
      "\x0f\x37\x7d\x44\x7f\xc3\x2c\xef\x7a\x07\x3b\xe2\xb9\x9b\x15\xc6"
      "\xa6\xb5\xdf\x02\x12\x75\x7d\x8c\x09\x1a\x50\x91\x70\x46\xbb\x18"
      "\xf7\x44\x05\xc8\xdb\x78\xa2\x87\xd6\x0a\x5f\x14\xf0\xaf\x61\xd7"
      "\x14\x91\x31\xae\xad\xea\x05\xb3\xd7\xc3\xae\x57\xe5\xbe\x9a\x43"
      "\xde\x55\xcc\x8e\x91\xac\x5c\xb5\xb9\x0a\x68\x28\x41\xdc\x09\x69"
      "\x0b\x86\xa1\x46\x67\x96\x04\xf6\x2e\x6e\x07\x11\x62\xb5\x96\x09"
      "\x2b\x5f\xcb\x7a\x9b\xcb\x77\x1b\x79\xb0\xab\x05\x89\x15\x5a\xcd"
      "\xab\xd6\x82\x8c\xb0\x65\xc1\x88\x6c\x14\x60\x3d\x77\xf7\xb4\xc1"
      "\xdf\x43\x0a\x80\x37\xc4\x82\x31\x27\x93\x2d\x93\x06\xfb\x92\xce"
      "\x19\x3b\xb8\xcf\x4f\x42\xf6\x44\x7a\x5d\xed\xe7\x09\x79\x19\x42"
      "\xb8\x30\x7e\x4b\x36\xd9\x75\x46\xd8\x7b\xba\x32\x01\x29\x8b\xec"
      "\xdb\x66\xcf\x4b\x04\xde\x8d\x5e\x1d\xf1\x58\xc1\x3b\xcb\x04\x13"
      "\x3d\x8a\x9e\xa8\x8f\xce\x0c\xed\x8c\x1e\xf0\x3e\x8c\x59\x14\x53"
      "\x17\x9d\xb8\x47\x33\xbc\xa3\xe2\xdc\x16\xaf\xd2\x28\xe4\xfe\xa1"
      "\xaf\x98\x7a\xc9\x4b\x3b\x38\xea\x8e\x1a\x36\x3d\xb4\xb8\x9d\x28"
      "\xbc\xc6\x9f\xd4\x21\xa9\x52\xbd\x1c\x77\x69\xb8\x41\x0e\x66\x9a"
      "\x29\x99\x50\x4c\x76\x46\x99\xcc\xbc\x5a\x23\x1c\x19\xbb\x25\x07"
      "\xf5\xb3\x5c\x38\x9d\xed\xc5\x85\xea\xb4\xd6\x14\xdb\xd1\x54\xb7"
      "\x13\xec\xcb\x24\xce\x8c\xf9\xb5\xc7\xbe\x54\x17\x29\x19\xa2\xaf"
      "\xb6\xd3\x14\xae\x83\xa7\x43\xb7\xbe\x28\xba\x2c\x52\xc0\xaa\x37"
      "\x98\x14\x87\xe9\xbd\x2e\x1c\x93\x29\xd4\xad\x87\x4e\x9a\x7b\x94"
      "\x30\x72\x68\x31\x2c\xa5\x2b\xed\x52\xc9\x31\x43\xf1\x2c\x77\xcb"
      "\x73\x64\x07\x3f\x8a\x59\x59\xf3\x8a\x9c\x9e\xb0\xb6\x7b\x8d\x0e"
      "\x6b\x5a\x33\xcd\x04\x5e\x77\x93\xd4\x23\xb0\xbe\xca\x08\x95\xd6"
      "\x02\xd2\x22\xbb\x8d\x4c\xbc\x68\x6b\xc7\x6f\x47\x3d\x78\x4e\x56"
      "\xaf\x86\x11\x9f\x8b\x16\x22\x8b\x93\x89\x10\x58\xaa\x1a\xaf\x97"
      "\xc7\x33\x97\xcd\x6d\xb2\x17\xa3\x90\xd5\x92\x5e\xb7\xeb\x9f\x13"
      "\x02\x34\xa3\x2c\xe8\x0c\xc9\xf0\xe6\xda\x06\x70\xe5\x87\xe9\xbf"
      "\x8e\x68\x34\x5a\xfb\xe5\x39\x6a\xde\xc4\x15\xae\x4c\xe0\x6e\x0b"
      "\x42\x2f\x2a\x77\xd3\x5b\x69\xa0\x07\xaf\x1c\x55\xa8\x28\x24\x81"
      "\xc0\x34\xd5\xde\xca\xcf\xa9\x85\x58\x90\xd4\x5b\xf3\x73\xd1\xfb"
      "\xc4\x25\x64\xb0\x15\xf6\x98\x73\x65\x38\x89\x72\xa6\x5b\x5e\xdb"
      "\xca\x92\xeb\x39\xb9\x90\x29\x18\x72\xeb\xee\xa0\x90\x1a\x34\x4c"
      "\x62\x4f\xd9\x2f\x69\x49\x88\x4c\x24\x26\x02\x3b\x74\x12\xf1\x4c"
      "\x78\x25\xbb\xd3\x26\xc9\x25\xf0\xda\x68\x5a\x50\x7b\x69\x90\x9e"
      "\xd7\x50\x07\x9d\x4d\xec\x0b\xf8\x88\x78\x2b\xb9\x9e\x9a\x41\x40"
      "\x7f\xbe\xad\x6f\x4d\x3e\x83\x7f\x6a\x89\x79\x32\x68\x97\x37\x96"
      "\x90\x41\xde\x3a\x69\x49\xf3\x7e\x0a\xb6\x4a\x0f\x3c\x41\x69\x8a"
      "\xcb\xad\xb7\xe7\xf4\x59\x95\xa5\xf4\x8d\xac\xeb\xdf\x07\xf3\x1e"
      "\x81\x52\x66\x19\xb4\x07\xe6\x63\x0e\xda\x2d\x0e\xf6\x72\x94\x84"
      "\x53\x70\x22\x0e\x46\xa6\xe5\x4e\x9d\x34\x38\xa1\x6d\x2b\xdf\xa9"
      "\x67\x33\x81\xcf\xa5\x92\xff\x94\x2b\x19\x1f\x55\x05\xd8\xbc\x2d"
      "\xab\x7b\x15\xa2\x4c\xe7\xcb\xdb\x96\xfc\xb2\x51\x34\xb4\x84\xba"
      "\x1d\x68\x7a\xff\x64\x71\xa8\x46\x12\x97\xe6\xf5\x14\x4e\xf5\xcb"
      "\x72\xce\xaf\x3e\xf7\x60\x27\x42\xa0\x92\xdf\x90\x86\x40\x55\x94"
      "\x95\x11\xf4\xe4\xbf\xbc\x6e\xa6\x7f\x3f\x01\x8c\xa6\x01\xa2\x4e"
      "\x4e\x4d\xaf\x62\x3b\x55\x8d\x91\x34\x35\x43\x23\x51\x3b\xf6\x3e"
      "\xbd\x79\x04\x25\x20\xc1\x13\x23\xe2\x46\x78\xde\xd5\x0d\xb6\x89"
      "\x2c\x43\x71\x9a\x89\x8a\x3c\x70\xee\x20\x6b\x8b\x9c\x31\x48\x3a"
      "\x41\x9a\xde\xf0\x18\x46\xee\x47\x09\xcb\xad\x2a\x6b\x95\x2d\x72"
      "\xd7\x01\xf8\x68\xfe\x75\x37\x15\x6a\x15\x65\x8e\x95\x88\x66\x08"
      "\xea\x31\x6d\xee\x8f\xc9\xac\x01\x06\x89\x3a\x82\x35\x79\x0a\x40"
      "\x37\x51\x1a\x53\xd9\x85\xd6\x99\x12\xbf\xb6\xe0\x72\x3c\xc2\xfe"
      "\x07\x1e\x92\xce\x18\x9f\xfb\xa0\xf6\xd3\x42\xbb\x41\xce\x31\x61"
      "\x2f\xe1\x8d\x55\x80\x03\x16\xb0\xd9\x2d\xd3\x64\xca\x62\x49\x5f"
      "\x3e\x28\xe6\x54\xd5\xb9\xdf\x7f\x5a\xcb\xa2\x87\xbc\x34\xbe\x06"
      "\x0a\x4c\x77\x34\xa6\xae\xbd\xad\x22\x62\xf2\x56\x28\x99\x21\x4b"
      "\x58\x68\x1f\xa5\xb6\x89\x5e\xa4\x76\x58\x60\x8a\x61\x17\x63\x77"
      "\xbd\xef\x1c\x3e\xfd\xc2\x26\x29\x69\xd9\xa0\x6e\xef\x81\x6d\xec"
      "\xa0\x14\xac\x42\x47\x77\xd5\x1e\xa5\xc7\x40\xa3\x7e\xac\x80\xf7"
      "\x1f\x25\xa7\x04\x58\xbe\x65\x32\xe2\xb0\x47\x9d\x71\xa1\x5c\x60"
      "\x25\xa6\x9c\xb4\x9d\x6f\xf3\xfc\x66\x51\x50\xaa\x98\x1b\x16\x57"
      "\x66\xb8\xcc\x81\x30\x7c\x25\xd9\x6e\xef\x86\x3e\x05\xf5\x58\x51"
      "\xd5\x5f\xec\x3b\x78\x5e\xe1\x20\x1b\x44\x8d\xee\x3d\x01\xd2\xbe"
      "\x72\x54\x46\x71\xd7\x38\x65\xa4\xf8\x75\xa5\x30\xca\x74\x20\xb8"
      "\xbe\xcf\x6f\x59\xa6\x52\x7b\x23\x4b\xf5\x90\x50\x12\x85\xf1\xd6"
      "\xa2\x75\xf4\xd9\xd6\x52\xb1\xcd\x0b\x1f\x79\xfa\x0a\xda\xa0\x70"
      "\xa1\x02\x78\xcb\xc4\x68\x16\x3f\xc4\x87\x6a\x0e\xb6\xba\x09\x26"
      "\x3d\xc0\x0f\x38\xbd\x38\x4f\x04\x92\xdb\xe5\x2d\xf6\x07\x74\xcf"
      "\x66\x9b\x02\x2f\x49\x71\xf8\x3c\xd2\x9c\x31\x5d\x3b\xd0\x17\x8d"
      "\x90\xf3\x58\x4c\x5e\x41\xb7\x6e\x8c\xe4\x73\xd3\xd5\x76\x1b\x94"
      "\xb0\x08\x11\xf7\x9e\x08\x4f\x3a\xd7\xdb\x69\x47\x77\xbb\xae\xc2"
      "\x85\xf9\xfb\x0c\x1e\xfa\xaa\xb9\xe7\xb4\x1c\x1d\xf0\x4d\xd3\x95"
      "\x57\x12\xea\xc4\x21\xb2\xa6\x45\x26\x4d\x1c\x91\xf0\x69\xda\xa1"
      "\x09\x05\xd7\x6c\xe4\x3a\x08\xc8\x2d\xf0\x8b\xc8\x21\x99\xad\xf4"
      "\xb9\x9c\x2a\x86\x88\xf1\x40\x31\xe0\xb4\xe8\xdd\xaf\x59\x0b\x38"
      "\x9a\x57\xfb\xa0\x9c\xdc\x1d\xca\xab\x51\xb3\x20\xaa\x71\xca\x01"
      "\x4a\x85\x3f\x5c\x0c\x3f\x22\x73\x0d\x0f\xbf\x3e\x0f\x05\x26\xb0"
      "\xd0\x48\xb4\xe2\x5b\x83\xbd\x90\x30\x9e\xf3\xbd\xd6\x78\xc4\x7d"
      "\x8a\xe8\x88\x72\x14\x30\x11\x51\xf3\x8d\x44\x8c\x17\xc2\x22\x04"
      "\xcc\xea\x02\x38\x23\x43\x3a\x77\x1d\xcd\x95\xc2\xa2\xc2\xbc\xef"
      "\x26\xec\x54\xab\xe3\x80\x7e\x77\x3b\xdf\x6a\xb9\x7e\xbf\x40\x93"
      "\x87\x6d\x0e\x66\xb9\xce\x95\x1c\xb5\x2b\x86\x16\x90\x67\x1a\x87"
      "\xe7\x96\x59\xb4\x96\x44\xf9\x31\x0c\x0c\xab\x1f\xfc\xac\x29\xee"
      "\xbd\x51\x64\xb4\x21\x51\xf9\x4a\x74\x08\xaa\xbb\x49\xad\xf8\xc6"
      "\x9f\x41\xe5\x30\xf9\xd1\x5b\x32\x4b\x0a\xb9\xba\x3a\xac\x90\xa1"
      "\x12\xd7\x36\x8b\xba\x86\xe2\xe7\x5c\x3d\x27\xce\x8f\x83\x0a\x59"
      "\x28\x6f\xe3\x71\x93\x4d\x89\xc1\x39\x3a\x0f\xdf\x68\x03\xe8\xf2"
      "\x95\xa9\x71\x0f\x6d\xd5\x1d\xba\x50\x3c\x6a\xfe\xcf\xdd\xc4\x98"
      "\xf3\xf2\xe8\x8a\xd6\xca\xfc\xb1\x42\x21\x37\x52\x97\xfb\x8d\x0a"
      "\xe7\x72\x65\xc3\x4a\xf8\x4c\xb8\x04\xdd\x2e\x8e\xcd\xb3\x68\xe1"
      "\xbf\x9c\xd3\xef\x0c\xe0\xda\xff\x9c\x6f\xab\xcc\x97\x53\xfa\xdd"
      "\xd5\x47\xf1\xaa\x89\x9e\xa2\x1a\x5e\xb4\x18\xb3\x3f\xf8\xb8\x49"
      "\x61\x81\xac\xd0\x5a\x7b\x5c\x77\x96\x4e\xd9\x70\x54\x69\x78\xd4"
      "\x4e\xc1\xba\xe5\x0a\xc9\xec\x44\xd6\x00\x66\xe7\xd8\x31\x51\x7f"
      "\x18\xef\xee\x6a\x6c\xb9\x27\x34\xe9\x91\x28\x54\xd4\x39\xf0\x82"
      "\x6d\xa7\x26\x85\x34\x3b\x59\x7a\x2a\x94\xfb\x34\x0d\x84\xae\xc2"
      "\x18\x79\x2d\x4a\xb0\xf9\x62\xdf\x3e\x5e\x71\x13\x6e\x22\xb9\xdb"
      "\x15\xce\xf1\xad\x69\x48\xb3\x61\x27\x83\x7d\xdc\x5b\xdb\x20\x66"
      "\x39\x24\x21\xac\xd6\xac\xca\xfb\x6e\x05\xd6\x1e\x32\xa7\xbf\x81"
      "\x3f\xb3\x18\x8a\x31\xbb\x1e\x67\x21\x93\x4b\xb1\x14\x54\xfd\xfe"
      "\x4e\xaa\x8c\xdc\x12\x02\x72\x14\x8e\x01\xf7\xe8\xbc\x1b\x6c\x6a"
      "\x1b\xe6\xb2\xbd\x69\x5e\x75\x54\xa7\xf0\x3a\x84\x2e\x5a\x65\x4e"
      "\x70\x81\x31\xdd\xde\x36\xaa\x2d\xdd\xed\x8e\x3a\x54\x80\x5a\xac"
      "\xce\x1c\x48\xb9\xc3\x44\x1a\x94\xe0\xb3\x34\x19\xba\x08\x74\x8a"
      "\xf5\x0e\x74\x35\x78\x83\x15\xe2\x41\xba\x4a\x21\xb9\xd9\x03\x01"
      "\x58\x03\x2b\xa6\xc3\x26\xcf\x8e\x8c\x27\x4f\x2d\x59\x0c\xca\xf3"
      "\xa6\xe9\xa1\xaf\x34\x43\x35\x1f\x55\x36\x3a\x6a\x5e\xe5\x41\xf8"
      "\xd5\x18\xe8\x31\x31\xc4\x4e\x66\xe4\x10\x43\x81\x43\xb2\xe7\xab"
      "\xe6\xe6\x3f\x8f\xb3\xd9\xd9\x79\xf6\xc8\xfb\x8f\x6e\xee\xba\x3e"
      "\x43\x5d\x8e\xca\xcb\x05\x34\x43\x2c\xb3\x6b\xc9\xbd\x27\xfe\xcf"
      "\xe6\x38\x86\xdc\x98\xb0\x0f\x13\x92\xf2\x91\x57\x51\xb2\xd2\x5b"
      "\x84\xef\x5c\xd2\xa4\x75\x82\x54\x24\x74\x5a\x4a\xee\x82\x2d\xaa"
      "\x1e\x97\x2e\xae\x77\x75\x6c\x39\x2f\x13\x71\xab\x8e\x19\xbc\x49"
      "\x1a\x14\x1a\xc9\x26\xcd\xc3\x0d\x31\xf2\x7e\x1c\x85\x38\x24\x04"
      "\x60\x54\x2b\xfe\xec\x8b\xbc\xc0\x71\xe6\xc2\x8d\xe1\x82\x8b\xf0"
      "\xae\xed\x06\x7c\x2f\x93\x3d\xfb\x9a\x61\xc3\xac\x96\xf7\x24\x4a"
      "\x69\xc8\x26\x2c\xba\x42\x0c\x11\xf5\x65\x20\x62\x73\x37\x59\xca"
      "\xe9\x50\xe2\xb0\x20\x4c\x79\x90\xe2\x24\xc3\x99\xaa\x79\x0b\x92"
      "\x57\x6f\x91\x96\x3d\xe8\xd5\xb1\x34\x12\xaa\xb9\x43\x6f\xed\xec"
      "\xbc\x7f\xe7\xeb\xab\x73\x52\x5f\x59\x63\x04\x1f\xa2\x6e\x08\x41"
      "\x43\x28\xd1\xdf\xfe\xbc\x76\x27\xa1\x8c\xd3\x30\xc5\xe3\xf7\x31"
      "\xdc\x59\xc2\x95\x86\x71\xcd\x89\xeb\xeb\x76\x93\xcf\xb1\xa0\xa3"
      "\x42\x3e\x34\x24\x77\x1e\x58\x1a\x99\x46\xe1\x8a\xd9\xe9\xad\xdc"
      "\xcb\xdc\x75\x5c\x36\x17\x2a\x92\x5d\x7d\x05\xc9\xee\x68\x3e\x69"
      "\x67\xb8\x89\x7b\x7e\xba\x85\x88\xa0\xf3\xef\xab\x84\x2b\xa5\x7c"
      "\x54\x57\xf6\xac\x65\xd1\x93\x29\xb5\x61\xc7\xcb\x6c\x33\x86\xae"
      "\x31\x2b\xe8\x65\x95\xc8\xb6\x76\x64\x63\x05\x02\xc5\x4b\x32\xe6"
      "\x41\x4c\xfc\xd0\xd4\xe4\x69\x14\xf0\xc0\x80\x5f\x0b\xb9\x94\x92"
      "\xf7\x58\xdf\x68\xb2\x7f\x74\x1e\xc4\xd0\x41\xf1\x9d\xe9\x60\x02"
      "\xf1\x0f\x41\xb8\x4c\x1a\x8f\xcb\xed\x47\xc6\xb1\xa4\x46\x63\x1e"
      "\xcb\xc7\xe5\x75\x44\x82\x44\x5a\x5b\x0a\x62\xd3\x85\xfd\x0d\x72"
      "\xc6\x1b\x3a\x35\xc8\xd9\xd0\x92\xc1\xd7\xcd\x9a\xbf\x33\x01\xa3"
      "\xe0\x9c\x58\x73\x36\x56\xc8\x26\x8d\xc3\xb6\x98\xe5\x87\x79\x91"
      "\xf2\x8f\x4d\x5a\x68\x13\xbd\x37\xa6\xf1\x9a\x2e\xe6\x22\xfa\x71"
      "\x43\x17\x9a\x93\xa9\x82\x2c\xb8\xee\x54\x38\x31\xbc\x64\x54\x20"
      "\x61\x48\x1c\xfa\xde\xf0\x49\xfd\x34\xb1\xee\x06\x94\x63\xd5\x27"
      "\x10\xde\x2b\xbe\x97\x76\x6f\xc1\x65\x2f\x81\x36\xc6\x62\xef\x48"
      "\xf4\x5b\xb2\x02\x9b\x1c\x24\x98\xbb\xed\x3e\xe8\x85\xc3\xe2\x45"
      "\xdb\x69\x35\xd5\x97\xf9\x86\x5c\x8a\xe2\xd4\x33\xaf\x3b\x1c\xbc"
      "\x8a\xf5\xfb\x9d\x83\xec\x73\x00\x0a\xd3\xca\x10\xe5\x3e\x38\x1e"
      "\x5e\xfd\xb9\x54\x92\xe0\x44\x08\x7f\xeb\xb7\x59\x49\x48\x15\x0d"
      "\x85\xb0\x72\x4d\xc0\x99\x4e\x66\x3b\xd5\x0d\xaa\xb4\xf8\xb6\x9a"
      "\x8b\xc9\x8d\x6e\x2f\x7a\xb4\xd5\xe3\x00\x82\x80\xa5\x70\x34\xdf"
      "\xb1\x5c\xd1\xab\x8b\x64\x56\x43\x9e\xb4\x91\x5f\x0e\x90\x3f\xd8"
      "\xd0\xe3\xfc\x31\x13\x0a\x04\xbe\x4b\x2a\x2a\xdf\x44\x4c\xb2\x69"
      "\xab\xe0\x8a\x11\x2c\x01\xe6\x59\x2f\x07\x51\x84\xa4\x85\x94\x46"
      "\xe9\x30\x9f\xf5\x91\x25\x93\x85\x93\xe9\xd6\x35\x9f\x5f\x85\xa6"
      "\x7b\x59\x92\xb1\x7a\x79\xc6\x71\x0d\xc7\xd3\x20\xfa\x84\xcc\xf4"
      "\xab\x4c\xf7\xd2\xe6\xd7\xec\x62\x85\x52\x2f\x1f\x4c\x92\x8e\x85"
      "\x93\x3c\x6f\xfd\xe8\xb9\xaa\xec\x9b\xe7\x0d\xa4\x1b\x13\x31\x97"
      "\x29\x20\x3d\xc5\xd0\xd4\x4d\xec\x4a\x18\x9c\x28\x48\xa3\x6c\x14"
      "\x86\x5d\xe0\xc1\x60\x6d\x90\x5d\xaa\x6c\x70\xbd\x6a\xe0\x68\xb5"
      "\x74\x8c\x46\x09\x86\x9a\xb1\xba\xe4\xf6\x3f\xd0\x88\x1f\x54\x83"
      "\x14\x17\x5b\x5a\x52\xd5\x72\x09\x22\x28\xdb\x18\x2d\xeb\xac\x59"
      "\x10\x1b\x88\x6d\x45\xa7\x2e\x19\xfd\xdc\x4f\xb1\x1f\xde\x8d\xcc"
      "\x95\xbe\x19\x56\x22\x10\x89\x68\x80\x4e\x7c\x7e\xac\xba\xce\x73"
      "\x2b\x1b\x8c\x38\x85\x59\x9d\xa7\x12\xb5\x8c\x0e\x7f\xd3\x2b\xf5"
      "\x9d\x46\xe8\x65\xc8\xe5\x40\x9e\x6b\x84\x0b\x5a\xc7\x52\x89\x59"
      "\x35\x57\x8f\x71\x0a\x37\xc0\xf0\xf3\x0f\x06\xd2\x8e\xab\x2a\x92"
      "\xf3\x4e\x5e\x14\xe0\xfd\x04\xa0\xc1\x5a\x93\x52\x31\x45\x14\x77"
      "\x1d\xe6\x81\x49\xca\xe3\x7f\xf0\x89\x80\x3e\x6a\x49\xbc\x6c\x0b"
      "\xb5\x46\x3f\x32\x48\x3e\x9c\x61\x3b\x50\xf4\x18\x48\x83\xb5\x19"
      "\x22\x35\x5b\x08\xcb\xb2\x89\x87\x4d\x1f\xb3\xd6\xaf\x4a\x02\xe8"
      "\x9e\xe0\xdc\x04\xc7\x25\x4e\x49\xe6\x5a\xb5\x43\x68\x26\x0d\xb6"
      "\xd2\x64\xbe\x27\x79\x30\xf0\x2b\xd5\x13\xca\x99\x6b\x2d\x6a\x0e"
      "\x40\xa7\x1d\xcc\xb7\x4f\xec\xdc\x23\x06\xb1\x3a\xd8\xe1\x24\x86"
      "\xde\x73\xa4\x22\x7c\x5d\xd8\x6f\xbd\xdc\xd9\xab\x8d\x7b\x16\x22"
      "\xa7\x6b\xd8\x8a\xdf\x5f\xa0\x3b\x34\x11\xc9\x40\x6f\xab\xc2\x37"
      "\xdc\x6b\xd2\x25\x44\xa5\xc7\xec\x67\x0c\x3f\xf6\xba\x77\x53\x2e"
      "\xd0\xae\xc2\x0e\xe2\x56\x2d\x72\x92\xb2\x91\xfe\x04\x89\xc3\x34"
      "\x20\x6d\x8a\x92\xb1\x1a\xfc\xff\xcd\xd9\xc0\xc1\xa0\xa7\x7d\x9e"
      "\xe8\x5e\x76\xf1\x81\x03\xdf\xd4\x0b\x98\x0a\x36\xd4\x1a\x50\xd0"
      "\xe3\x2f\x51\xc2\xd8\x4e\xc9\x77\xbc\xb8\x7f\x38\xe3\x00\xdb\x2f"
      "\xbc\x48\x16\x6a\x28\xcf\x56\xd2\x58\x01\xbb\x21\x72\x55\xfa\x3c"
      "\xd3\xc9\x04\x80\xdc\x38\xa6\xa5\xcd\xed\xba\xd1\xbc\xb7\x9a\x7e"
      "\xb4\xe8\x59\x2a\x8d\x2e\xcf\x7c\xdd\x31\xf7\x8b\x96\x71\xf0\x06"
      "\xfb\x29\x23\xf6\x0d\x66\x59\x8e\x82\x95\x8d\x42\x8e\x4e\x01\x9e"
      "\x6d\x19\x83\x04\x36\x3d\xe3\x8a\xc4\x54\x90\x23\xa9\x81\xda\xcb"
      "\x08\x6f\x9a\xd2\x13\x8d\x46\x1c\x4d\xf3\xa9\x3e\x60\x5d\x90\x3b"
      "\xca\x95\x82\x1b\xa2\x1a\x19\xc5\x5c\x5a\xc9\x67\xcf\x65\xe4\x8d"
      "\xb2\x2b\x4e\x0c\x7f\x7b\xfa\x32\x49\x69\xda\x5a\xb4\x9c\x06\xbf"
      "\x12\xa4\x0f\x4a\x8c\xd0\x73\x8e\xdf\x66\x72\xd9\x29\xab\x06\x3a"
      "\xf1\x3c\xd8\x30\xd6\xbb\x0e\x37\x07\x4e\xe5\xf6\x87\x8a\x4a\xd0"
      "\x66\x68\x84\xd1\x23\x62\xb6\x07\x77\x0e\x60\x7d\x30\x22\xc2\xff"
      "\x53\x46\x60\x69\xb0\x73\xe5\x33\x25\x0b\x47\x68\xa0\xf4\x52\x3d"
      "\x91\x6e\x1c\x4d\x9e\x0a\x16\xd5\xb3\x3b\x2d\x3a\x7a\x87\x6c\xfe"
      "\x7b\xc8\x81\xa8\xe6\xce\xb9\xb3\xc5\xc2\xd1\xde\x90\x92\x0f\x57"
      "\x71\x90\x6a\x73\x4b\x5b\x07\x97\xe6\xda\x7d\xdb\xd5\xd1\x3e\xa6"
      "\xbf\x26\x23\x46\xc6\xcf\xef\x2a\xed\xa7\xc0\x52\xda\x40\x2e\xd6"
      "\x2e\xc4\xf1\xb2\x2f\x69\xac\x73\xe4\x2d\x75\xea\x19\x4c\xb5\x50"
      "\xbc\x03\x51\x9c\x05\xda\x8a\x3b\xc9\x98\xd2\x43\x40\xc6\xd9\x0f"
      "\x53\x2e\x24\x56\x55\x4e\x41\xc9\xcd\xa9\x06\xe8\xbc\x69\x10\xaa"
      "\x99\x3d\x56\x9e\xd2\xbc\x48\xcd\x58\x2d\xe3\x16\x6a\x23\x3d\x85"
      "\xc5\x14\x80\x46\x07\x96\xcf\xd9\xdc\xff\x14\x39\xfd\x5c\xc2\x2d"
      "\xb9\xf9\x51\x09\x5d\xd3\xe4\xf6\x3f\x51\x62\x10\xf6\xd4\x76\x78"
      "\x11\xf0\xd5\x63\xb8\x53\x2b\xb2\xa0\x58\x4e\x71\x90\xea\xb6\xc6"
      "\x92\x59\x06\x8d\x53\x63\x0a\x0c\xd4\x62\x2d\x57\x12\xf9\xf8\xd8"
      "\xdb\x10\x40\x2e\x09\x83\x1b\xbb\x8c\xdd\xbc\x0c\xa0\xc8\x14\x23"
      "\xa5\x93\xed\xd9\x2d\x0b\xc0\xfd\x0e\x1d\xd1\xbb\x95\x96\xb6\xbc"
      "\x81\x31\x6f\x20\x6f\x72\x1c\x4a\x87\xfb\x66\x2d\x79\x3c\xa4\x6d"
      "\x05\xc1\x71\x50\x83\xad\xea\x03\x26\x2b\xe4\x10\xc8\x33\x0b\x61"
      "\xdf\x30\x4b\x27\x8f\xfe\xbd\xcc\x8d\xda\x4f\xaf\x8f\xad\xaa\x25"
      "\xa1\x50\x95\x95\x7d\x8e\x35\xec\xe8\x7e\xd4\x98\x68\xe4\x95\xac"
      "\xa6\x98\x95\x38\xf8\xd2\xab\xdc\xb9\x77\xfc\xa9\xbf\xb5\x18\xed"
      "\xca\x15\xb2\xe7\xd0\x23\xcb\xc4\x73\xc0\x85\x0b\x57\xeb\xf4\xe6"
      "\x11\x97\xb1\x03\xa6\x66\x0a\x24\x3b\xb6\xe8\x2f\xfe\x9c\x78\x0a"
      "\x42\x01\xe9\x35\x58\xf7\x55\x13\x80\x24\x23\x30\x62\x6c\x7b\x86"
      "\xff\x7e\x12\x34\xf3\x33\x4c\x1c\xed\x5a\x96\xd6\xcd\x04\xfb\xf9"
      "\x7c\xde\xc0\xd5\x70\x52\x4e\x0f\xa2\x8e\x6b\xa6\x8f\x3a\x08\xf9"
      "\x08\x0f\x2f\xd7\xa2\xb1\x91\x53\x65\x63\x63\xb8\x31\xba\xf4\x21"
      "\xb5\x17\xd7\x59\x94\xd0\x0e\x8c\x91\x5c\x37\xf8\x3a\xd8\x8c\x7f"
      "\x76\xd0\x63\x7a\xd9\xb4\xa6\x3d\xf8\xfb\x72\xd5\x65\xf0\x10\x4a"
      "\x42\x15\x70\xb1\x9b\x5f\xf8\xf9\x9f\x5b\x29\x0a\x28\x2a\x68\x6b"
      "\xaf\xec\x84\x94\xbc\x22\xdf\xe8\x3e\xcb\xee\xc3\xc8\x03\x00\xf3"
      "\x02\xff\x07\x4d\x95\x62\x12\x9e\x51\x1a\x20\x4a\x5a\xa2\x66\x81"
      "\x3d\x29\x98\x23\x17\x11\x95\x84\x51\x9f\x40\x7a\x3d\x6f\x61\xbe"
      "\x2b\x1b\x03\x82\xad\xb6\x8f\x69\x3d\x31\x39\xc7\x8b\x0a\x77\x6e"
      "\x02\x88\xdd\x13\x6a\x9c\x72\x46\x5d\xf0\x92\xb4\x76\xac\xc0\xbd"
      "\x8d\x2e\x3c\xcb\xa3\x89\x31\x07\x36\x68\x35\x03\x4c\x95\x6d"
      "\xbd",
      4096);
  r[18] = syscall(SYS_writev, r[2], 0x20013ffeul, 0x5ul, 0, 0, 0);
  return 0;
}

On commit 34229b277480f46c1e9a19f027f30b074512e68b.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* sound: out-of-bounds write in snd_rawmidi_kernel_write1
@ 2016-02-03  8:57 ` Dmitry Vyukov
  0 siblings, 0 replies; 13+ messages in thread
From: Dmitry Vyukov @ 2016-02-03  8:57 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai, alsa-devel, LKML
  Cc: Kostya Serebryany, syzkaller, Alexander Potapenko, Sasha Levin

Hello,

The following program triggers an out-of-bounds write in
snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
copy -1 bytes (aka 4GB) from user space into kernel smashing all on
its way.

==================================================================
BUG: KASAN: use-after-free in memset+0x1a/0x30 at addr ffff8800326e3cef
Write of size 4294950912 by task a.out/7292
=============================================================================
BUG kmalloc-4096 (Not tainted): kasan: bad access detected
-----------------------------------------------------------------------------

INFO: Allocated in open_substream+0x2ff/0x780 age=288 cpu=1 pid=7287
[<      none      >] ___slab_alloc+0x564/0x5b0 mm/slub.c:2470
[<      none      >] __slab_alloc+0x66/0xc0 mm/slub.c:2499
[<     inline     >] slab_alloc_node mm/slub.c:2562
[<     inline     >] slab_alloc mm/slub.c:2604
[<      none      >] kmem_cache_alloc_trace+0x25c/0x300 mm/slub.c:2621
[<     inline     >] kmalloc include/linux/slab.h:463
[<     inline     >] snd_rawmidi_runtime_create sound/core/rawmidi.c:127
[<      none      >] open_substream+0x2ff/0x780 sound/core/rawmidi.c:266
[<      none      >] rawmidi_open_priv+0x144/0x300 sound/core/rawmidi.c:312
[<      none      >] snd_rawmidi_open+0x3fb/0xa90 sound/core/rawmidi.c:416
[<      none      >] soundcore_open+0x30f/0x640 sound/sound_core.c:639
[<      none      >] chrdev_open+0x22a/0x4c0 fs/char_dev.c:388
[<      none      >] do_dentry_open+0x6a2/0xcb0 fs/open.c:736
[<      none      >] vfs_open+0x17b/0x1f0 fs/open.c:853
[<     inline     >] do_last fs/namei.c:3254
[<      none      >] path_openat+0xde9/0x5e30 fs/namei.c:3386
[<      none      >] do_filp_open+0x18e/0x250 fs/namei.c:3421
[<      none      >] do_sys_open+0x1fc/0x420 fs/open.c:1022
[<     inline     >] SYSC_open fs/open.c:1040
[<      none      >] SyS_open+0x2d/0x40 fs/open.c:1035
[<      none      >] entry_SYSCALL_64_fastpath+0x16/0x7a
arch/x86/entry/entry_64.S:185

Call Trace:
 [<ffffffff817654b7>] __asan_storeN+0x127/0x1a0 mm/kasan/kasan.c:522
 [<ffffffff8176582a>] memset+0x1a/0x30 mm/kasan/kasan.c:280
 [<ffffffff82c15294>] copy_user_handle_tail+0xb4/0xd0
arch/x86/lib/usercopy_64.c:86
 [<     inline     >] copy_from_user ./arch/x86/include/asm/uaccess.h:735
 [<ffffffff852855da>] snd_rawmidi_kernel_write1+0x34a/0x760
sound/core/rawmidi.c:1250
 [<ffffffff852878b3>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1318
 [<ffffffff817b8be1>] do_loop_readv_writev+0x141/0x1e0 fs/read_write.c:719
 [<ffffffff817bcb38>] do_readv_writev+0x5f8/0x6e0 fs/read_write.c:849
 [<ffffffff817bcd56>] vfs_writev+0x86/0xc0 fs/read_write.c:886
 [<     inline     >] SYSC_writev fs/read_write.c:919
 [<ffffffff817bfec1>] SyS_writev+0x111/0x2b0 fs/read_write.c:911
 [<ffffffff86661376>] entry_SYSCALL_64_fastpath+0x16/0x7a
arch/x86/entry/entry_64.S:185
==================================================================

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

long r[19];

int main()
{
  memset(r, -1, sizeof(r));
  r[0] = syscall(SYS_mmap, 0x20000000ul, 0x22000ul, 0x3ul, 0x32ul,
                 0xfffffffffffffffful, 0x0ul);
  r[2] = syscall(SYS_open, "/dev/midi3", 0x2ul, 0, 0, 0);
  *(uint64_t*)0x20013ffe = (uint64_t)0x20013f69;
  *(uint64_t*)0x20014006 = (uint64_t)0x97;
  *(uint64_t*)0x2001400e = (uint64_t)0x20003ffe;
  *(uint64_t*)0x20014016 = (uint64_t)0x3;
  *(uint64_t*)0x2001401e = (uint64_t)0x2001ef70;
  *(uint64_t*)0x20014026 = (uint64_t)0x92;
  *(uint64_t*)0x2001402e = (uint64_t)0x20014730;
  *(uint64_t*)0x20014036 = (uint64_t)0x1;
  *(uint64_t*)0x2001403e = (uint64_t)0x2001e000;
  *(uint64_t*)0x20014046 = (uint64_t)0x1000;
  memcpy((void*)0x20013f69,
         "\x0e\x6f\xfe\xa4\xc8\xbf\xaa\x28\x69\x82\xe0\x8c\x45\xab\x90"
         "\xb9\x6a\xeb\x50\x3d\x1a\x59\x59\x33\x0a\xa5\xb8\xfe\x83\x75"
         "\x1f\xb5\x25\x76\x65\x53\xb6\xe7\xe2\xe7\xe3\xd7\x55\x36\xb6"
         "\x59\x2f\xf8\x61\xda\xdb\x73\x32\x94\xb1\x0e\x17\x87\xad\x8f"
         "\x73\x6c\xc7\xeb\x47\xa2\x65\x77\xfb\xfc\xec\x70\x5c\x9e\x01"
         "\x78\xef\x1b\x69\xab\xef\x58\x13\x35\x99\xf0\x2b\x25\x99\xdb"
         "\xba\x16\xa7\x43\xc5\x19\x32\x91\x13\x24\x15\xd1\x5e\xb0\x1a"
         "\x5f\x63\xe2\xc3\x61\x9a\x79\x82\x57\x60\x21\x79\x6e\xf5\x21"
         "\x74\x18\xcf\x8f\x73\x93\x70\x3a\xfe\xf8\xe3\xde\x6a\x85\x3b"
         "\x5a\xfc\x0b\xfe\x02\x8f\x32\xe6\xc5\x14\x1c\x07\x24\xce\xcb"
         "\x95",
         151);
  memcpy((void*)0x20003ffe, "\x3d\x07\x31", 3);
  memcpy((void*)0x2001ef70,
         "\x5c\x39\xe0\x3f\xe7\xdd\x08\xeb\x7c\xb0\xe7\x31\x09\xdf\x84"
         "\x1a\xbb\x98\xe1\xc8\x08\x00\x3b\xe9\xef\x62\x4a\x18\x10\xff"
         "\xa1\x7f\xa0\xd6\x81\x86\xed\xb5\x43\x33\x7c\xa6\x01\xb8\xfc"
         "\xe1\xee\x43\x95\x05\xf1\x5d\xa6\xb4\xb1\x62\x74\x82\xc6\x8b"
         "\x9f\xfb\x9b\xe8\x41\xee\x2e\x44\xc0\x20\x37\xca\xe5\x33\xf3"
         "\xeb\x9e\x2e\x15\x56\xce\x26\x5e\x6c\xee\xca\x49\x00\xe6\xf2"
         "\x21\xd4\x07\xf1\x00\xee\x21\x5a\xd5\x7a\x84\x4c\x3e\x7c\x8d"
         "\xe5\xb5\x35\x57\x69\xe4\x18\x09\x5b\xa7\xdb\xe6\x2f\x56\x78"
         "\x83\xa1\x0c\xdd\x07\x74\x32\xb2\x85\x75\xeb\x51\x5b\x22\xd1"
         "\x57\x95\xcd\xc2\xc4\xf9\x2e\xd8\xce\x9a\x52",
         146);
  memcpy((void*)0x20014730, "\xc3", 1);
  memcpy(
      (void*)0x2001e000,
      "\xff\x20\xcc\xa3\x99\x07\x76\x17\xc4\x29\xef\xa5\x6a\xef\x9c\x9b"
      "\x58\x94\x16\xfc\x87\x60\xb1\x04\x16\x80\x1d\xcb\xfd\x8b\xd7\x9a"
      "\x41\x87\xb2\xdf\xe8\xc3\x17\x50\xd6\x5a\x01\x06\xc7\xc5\xb1\xf3"
      "\x56\x57\x81\xa8\x2c\x0b\x81\x67\x93\x59\xc1\xbb\xb5\x2d\x45\xc5"
      "\x27\x05\x66\x0b\xfd\x28\x1e\xdb\x45\x89\x34\x0b\x03\xfe\x5f\xa7"
      "\x47\xeb\xa1\xe0\xff\xe1\xdb\x12\xa7\x11\x37\xe0\x96\x53\xa2\x29"
      "\x1d\x3c\x3c\xda\x8e\x97\xeb\x58\x64\x8d\xff\x13\x70\x08\x96\x28"
      "\x32\x4e\xce\x4c\xb3\x17\x1c\x74\xa8\x8d\x7b\x78\x32\x4b\xcc\xf8"
      "\xf7\xcb\x33\x5c\xd5\x6b\xa3\x2a\x9c\x7c\x41\x3e\x87\x92\xec\x22"
      "\x44\x36\x28\x2d\x76\xde\x44\xa8\xef\x9d\x2c\xa2\xf2\xc5\x94\x2b"
      "\x3a\x17\xa4\xd7\x82\x4e\xef\xee\x1a\x4a\x6b\x98\xd5\xe4\x40\xbc"
      "\x5a\xe1\x76\x47\x17\x2b\x45\xb6\xb6\xa4\xeb\x5a\x54\x82\x6a\x98"
      "\x14\xf0\x4e\x5a\x8c\x30\x6a\x0f\xcb\x0f\x1b\x62\x8c\x48\x54\x16"
      "\xb8\x94\x28\xd0\xcc\x47\x4f\xb4\x01\x40\x3c\xb7\xed\xf0\x96\x2a"
      "\x55\xb2\xac\xf6\xa2\xab\x93\x19\x3f\xf6\xf8\xad\x8f\xa3\x5a\x6f"
      "\x15\x26\xa3\x25\xbb\x58\x6e\x02\x58\xfa\x3a\xcf\xd9\xf8\x17\xb9"
      "\xa1\x4c\x45\x16\x45\xcb\x7a\x84\x37\x3a\xb4\x3a\xc6\x98\xa9\x5c"
      "\xf4\x9e\xdb\xcf\xa9\xbb\xcc\xcb\x15\x36\x52\xb0\xcc\x3d\xd0\xfa"
      "\xd6\xc0\xff\xf6\xb7\x0e\x80\x31\x8e\x76\xfc\xe9\xd8\xf6\xb4\xbc"
      "\xfa\xec\x94\x13\x64\x9d\x13\x7e\x91\x9c\x10\x27\xda\xc8\xea\x9b"
      "\xc2\x09\x58\x81\x9e\x44\xf2\xc3\xef\x94\x6d\x2f\xa9\xa5\x19\xd7"
      "\x78\x61\x2e\xd3\x01\x8a\xc3\xac\x1b\xb9\xaa\x00\x12\xc5\x7e\x7f"
      "\x7b\x34\x27\x4c\x38\x00\x9c\x57\xa6\xe2\x5a\x5a\xe6\x00\x01\x56"
      "\xa2\xed\xa6\xcd\x95\x0b\xde\x5e\x09\x62\x61\x7c\x2b\x16\x13\xb4"
      "\x04\xf8\x1a\x5b\x15\x9d\x62\xd5\xac\x4b\x5b\x35\x70\xd0\xe2\x26"
      "\xf9\xc0\x7c\x73\xad\x9c\xd5\xef\x7b\x9f\x01\x8b\xb6\xb3\x85\xbf"
      "\x34\xa2\x8c\xce\x8a\xaf\xe1\x5b\xdd\x7f\xa6\x23\x55\x8b\xa4\xa3"
      "\x06\x2f\xf1\xa0\xd8\x2a\xcc\x9a\x94\x19\x22\xfe\x65\x69\x9b\xcb"
      "\x6d\x6c\x1c\x38\x25\x82\x9b\xec\xe1\x75\xb4\xbe\xac\x21\x4b\xec"
      "\xfd\x22\x76\xcb\x35\x4b\xaa\x5c\x3a\x7b\xaa\x6f\x3c\x68\xa7\xa5"
      "\x3d\xa2\xd5\x25\x9a\xe4\x6f\x80\xc5\xb5\xcf\x76\x37\xd8\xd9\x25"
      "\xe6\xc7\x26\x40\xdf\x1d\xd3\x41\xb2\x58\x69\xa7\x18\x57\xf8\x35"
      "\x26\x70\x30\x08\x76\xed\x2b\x37\x2a\x54\x7d\xa5\x7a\x66\x8d\xbf"
      "\x4a\x20\x3d\x1b\xd1\x28\x1e\x7e\xfe\xd3\xb1\x6c\x64\x87\x70\x27"
      "\x9e\xcf\x07\xd9\x5a\x9e\xbb\xdb\x3b\xb2\xcb\x50\x78\x3c\x45\x76"
      "\xec\x59\xa9\xca\xb2\x80\x8c\xc5\x62\x76\x8c\x76\x61\xb5\xf2\xcf"
      "\x0f\x37\x7d\x44\x7f\xc3\x2c\xef\x7a\x07\x3b\xe2\xb9\x9b\x15\xc6"
      "\xa6\xb5\xdf\x02\x12\x75\x7d\x8c\x09\x1a\x50\x91\x70\x46\xbb\x18"
      "\xf7\x44\x05\xc8\xdb\x78\xa2\x87\xd6\x0a\x5f\x14\xf0\xaf\x61\xd7"
      "\x14\x91\x31\xae\xad\xea\x05\xb3\xd7\xc3\xae\x57\xe5\xbe\x9a\x43"
      "\xde\x55\xcc\x8e\x91\xac\x5c\xb5\xb9\x0a\x68\x28\x41\xdc\x09\x69"
      "\x0b\x86\xa1\x46\x67\x96\x04\xf6\x2e\x6e\x07\x11\x62\xb5\x96\x09"
      "\x2b\x5f\xcb\x7a\x9b\xcb\x77\x1b\x79\xb0\xab\x05\x89\x15\x5a\xcd"
      "\xab\xd6\x82\x8c\xb0\x65\xc1\x88\x6c\x14\x60\x3d\x77\xf7\xb4\xc1"
      "\xdf\x43\x0a\x80\x37\xc4\x82\x31\x27\x93\x2d\x93\x06\xfb\x92\xce"
      "\x19\x3b\xb8\xcf\x4f\x42\xf6\x44\x7a\x5d\xed\xe7\x09\x79\x19\x42"
      "\xb8\x30\x7e\x4b\x36\xd9\x75\x46\xd8\x7b\xba\x32\x01\x29\x8b\xec"
      "\xdb\x66\xcf\x4b\x04\xde\x8d\x5e\x1d\xf1\x58\xc1\x3b\xcb\x04\x13"
      "\x3d\x8a\x9e\xa8\x8f\xce\x0c\xed\x8c\x1e\xf0\x3e\x8c\x59\x14\x53"
      "\x17\x9d\xb8\x47\x33\xbc\xa3\xe2\xdc\x16\xaf\xd2\x28\xe4\xfe\xa1"
      "\xaf\x98\x7a\xc9\x4b\x3b\x38\xea\x8e\x1a\x36\x3d\xb4\xb8\x9d\x28"
      "\xbc\xc6\x9f\xd4\x21\xa9\x52\xbd\x1c\x77\x69\xb8\x41\x0e\x66\x9a"
      "\x29\x99\x50\x4c\x76\x46\x99\xcc\xbc\x5a\x23\x1c\x19\xbb\x25\x07"
      "\xf5\xb3\x5c\x38\x9d\xed\xc5\x85\xea\xb4\xd6\x14\xdb\xd1\x54\xb7"
      "\x13\xec\xcb\x24\xce\x8c\xf9\xb5\xc7\xbe\x54\x17\x29\x19\xa2\xaf"
      "\xb6\xd3\x14\xae\x83\xa7\x43\xb7\xbe\x28\xba\x2c\x52\xc0\xaa\x37"
      "\x98\x14\x87\xe9\xbd\x2e\x1c\x93\x29\xd4\xad\x87\x4e\x9a\x7b\x94"
      "\x30\x72\x68\x31\x2c\xa5\x2b\xed\x52\xc9\x31\x43\xf1\x2c\x77\xcb"
      "\x73\x64\x07\x3f\x8a\x59\x59\xf3\x8a\x9c\x9e\xb0\xb6\x7b\x8d\x0e"
      "\x6b\x5a\x33\xcd\x04\x5e\x77\x93\xd4\x23\xb0\xbe\xca\x08\x95\xd6"
      "\x02\xd2\x22\xbb\x8d\x4c\xbc\x68\x6b\xc7\x6f\x47\x3d\x78\x4e\x56"
      "\xaf\x86\x11\x9f\x8b\x16\x22\x8b\x93\x89\x10\x58\xaa\x1a\xaf\x97"
      "\xc7\x33\x97\xcd\x6d\xb2\x17\xa3\x90\xd5\x92\x5e\xb7\xeb\x9f\x13"
      "\x02\x34\xa3\x2c\xe8\x0c\xc9\xf0\xe6\xda\x06\x70\xe5\x87\xe9\xbf"
      "\x8e\x68\x34\x5a\xfb\xe5\x39\x6a\xde\xc4\x15\xae\x4c\xe0\x6e\x0b"
      "\x42\x2f\x2a\x77\xd3\x5b\x69\xa0\x07\xaf\x1c\x55\xa8\x28\x24\x81"
      "\xc0\x34\xd5\xde\xca\xcf\xa9\x85\x58\x90\xd4\x5b\xf3\x73\xd1\xfb"
      "\xc4\x25\x64\xb0\x15\xf6\x98\x73\x65\x38\x89\x72\xa6\x5b\x5e\xdb"
      "\xca\x92\xeb\x39\xb9\x90\x29\x18\x72\xeb\xee\xa0\x90\x1a\x34\x4c"
      "\x62\x4f\xd9\x2f\x69\x49\x88\x4c\x24\x26\x02\x3b\x74\x12\xf1\x4c"
      "\x78\x25\xbb\xd3\x26\xc9\x25\xf0\xda\x68\x5a\x50\x7b\x69\x90\x9e"
      "\xd7\x50\x07\x9d\x4d\xec\x0b\xf8\x88\x78\x2b\xb9\x9e\x9a\x41\x40"
      "\x7f\xbe\xad\x6f\x4d\x3e\x83\x7f\x6a\x89\x79\x32\x68\x97\x37\x96"
      "\x90\x41\xde\x3a\x69\x49\xf3\x7e\x0a\xb6\x4a\x0f\x3c\x41\x69\x8a"
      "\xcb\xad\xb7\xe7\xf4\x59\x95\xa5\xf4\x8d\xac\xeb\xdf\x07\xf3\x1e"
      "\x81\x52\x66\x19\xb4\x07\xe6\x63\x0e\xda\x2d\x0e\xf6\x72\x94\x84"
      "\x53\x70\x22\x0e\x46\xa6\xe5\x4e\x9d\x34\x38\xa1\x6d\x2b\xdf\xa9"
      "\x67\x33\x81\xcf\xa5\x92\xff\x94\x2b\x19\x1f\x55\x05\xd8\xbc\x2d"
      "\xab\x7b\x15\xa2\x4c\xe7\xcb\xdb\x96\xfc\xb2\x51\x34\xb4\x84\xba"
      "\x1d\x68\x7a\xff\x64\x71\xa8\x46\x12\x97\xe6\xf5\x14\x4e\xf5\xcb"
      "\x72\xce\xaf\x3e\xf7\x60\x27\x42\xa0\x92\xdf\x90\x86\x40\x55\x94"
      "\x95\x11\xf4\xe4\xbf\xbc\x6e\xa6\x7f\x3f\x01\x8c\xa6\x01\xa2\x4e"
      "\x4e\x4d\xaf\x62\x3b\x55\x8d\x91\x34\x35\x43\x23\x51\x3b\xf6\x3e"
      "\xbd\x79\x04\x25\x20\xc1\x13\x23\xe2\x46\x78\xde\xd5\x0d\xb6\x89"
      "\x2c\x43\x71\x9a\x89\x8a\x3c\x70\xee\x20\x6b\x8b\x9c\x31\x48\x3a"
      "\x41\x9a\xde\xf0\x18\x46\xee\x47\x09\xcb\xad\x2a\x6b\x95\x2d\x72"
      "\xd7\x01\xf8\x68\xfe\x75\x37\x15\x6a\x15\x65\x8e\x95\x88\x66\x08"
      "\xea\x31\x6d\xee\x8f\xc9\xac\x01\x06\x89\x3a\x82\x35\x79\x0a\x40"
      "\x37\x51\x1a\x53\xd9\x85\xd6\x99\x12\xbf\xb6\xe0\x72\x3c\xc2\xfe"
      "\x07\x1e\x92\xce\x18\x9f\xfb\xa0\xf6\xd3\x42\xbb\x41\xce\x31\x61"
      "\x2f\xe1\x8d\x55\x80\x03\x16\xb0\xd9\x2d\xd3\x64\xca\x62\x49\x5f"
      "\x3e\x28\xe6\x54\xd5\xb9\xdf\x7f\x5a\xcb\xa2\x87\xbc\x34\xbe\x06"
      "\x0a\x4c\x77\x34\xa6\xae\xbd\xad\x22\x62\xf2\x56\x28\x99\x21\x4b"
      "\x58\x68\x1f\xa5\xb6\x89\x5e\xa4\x76\x58\x60\x8a\x61\x17\x63\x77"
      "\xbd\xef\x1c\x3e\xfd\xc2\x26\x29\x69\xd9\xa0\x6e\xef\x81\x6d\xec"
      "\xa0\x14\xac\x42\x47\x77\xd5\x1e\xa5\xc7\x40\xa3\x7e\xac\x80\xf7"
      "\x1f\x25\xa7\x04\x58\xbe\x65\x32\xe2\xb0\x47\x9d\x71\xa1\x5c\x60"
      "\x25\xa6\x9c\xb4\x9d\x6f\xf3\xfc\x66\x51\x50\xaa\x98\x1b\x16\x57"
      "\x66\xb8\xcc\x81\x30\x7c\x25\xd9\x6e\xef\x86\x3e\x05\xf5\x58\x51"
      "\xd5\x5f\xec\x3b\x78\x5e\xe1\x20\x1b\x44\x8d\xee\x3d\x01\xd2\xbe"
      "\x72\x54\x46\x71\xd7\x38\x65\xa4\xf8\x75\xa5\x30\xca\x74\x20\xb8"
      "\xbe\xcf\x6f\x59\xa6\x52\x7b\x23\x4b\xf5\x90\x50\x12\x85\xf1\xd6"
      "\xa2\x75\xf4\xd9\xd6\x52\xb1\xcd\x0b\x1f\x79\xfa\x0a\xda\xa0\x70"
      "\xa1\x02\x78\xcb\xc4\x68\x16\x3f\xc4\x87\x6a\x0e\xb6\xba\x09\x26"
      "\x3d\xc0\x0f\x38\xbd\x38\x4f\x04\x92\xdb\xe5\x2d\xf6\x07\x74\xcf"
      "\x66\x9b\x02\x2f\x49\x71\xf8\x3c\xd2\x9c\x31\x5d\x3b\xd0\x17\x8d"
      "\x90\xf3\x58\x4c\x5e\x41\xb7\x6e\x8c\xe4\x73\xd3\xd5\x76\x1b\x94"
      "\xb0\x08\x11\xf7\x9e\x08\x4f\x3a\xd7\xdb\x69\x47\x77\xbb\xae\xc2"
      "\x85\xf9\xfb\x0c\x1e\xfa\xaa\xb9\xe7\xb4\x1c\x1d\xf0\x4d\xd3\x95"
      "\x57\x12\xea\xc4\x21\xb2\xa6\x45\x26\x4d\x1c\x91\xf0\x69\xda\xa1"
      "\x09\x05\xd7\x6c\xe4\x3a\x08\xc8\x2d\xf0\x8b\xc8\x21\x99\xad\xf4"
      "\xb9\x9c\x2a\x86\x88\xf1\x40\x31\xe0\xb4\xe8\xdd\xaf\x59\x0b\x38"
      "\x9a\x57\xfb\xa0\x9c\xdc\x1d\xca\xab\x51\xb3\x20\xaa\x71\xca\x01"
      "\x4a\x85\x3f\x5c\x0c\x3f\x22\x73\x0d\x0f\xbf\x3e\x0f\x05\x26\xb0"
      "\xd0\x48\xb4\xe2\x5b\x83\xbd\x90\x30\x9e\xf3\xbd\xd6\x78\xc4\x7d"
      "\x8a\xe8\x88\x72\x14\x30\x11\x51\xf3\x8d\x44\x8c\x17\xc2\x22\x04"
      "\xcc\xea\x02\x38\x23\x43\x3a\x77\x1d\xcd\x95\xc2\xa2\xc2\xbc\xef"
      "\x26\xec\x54\xab\xe3\x80\x7e\x77\x3b\xdf\x6a\xb9\x7e\xbf\x40\x93"
      "\x87\x6d\x0e\x66\xb9\xce\x95\x1c\xb5\x2b\x86\x16\x90\x67\x1a\x87"
      "\xe7\x96\x59\xb4\x96\x44\xf9\x31\x0c\x0c\xab\x1f\xfc\xac\x29\xee"
      "\xbd\x51\x64\xb4\x21\x51\xf9\x4a\x74\x08\xaa\xbb\x49\xad\xf8\xc6"
      "\x9f\x41\xe5\x30\xf9\xd1\x5b\x32\x4b\x0a\xb9\xba\x3a\xac\x90\xa1"
      "\x12\xd7\x36\x8b\xba\x86\xe2\xe7\x5c\x3d\x27\xce\x8f\x83\x0a\x59"
      "\x28\x6f\xe3\x71\x93\x4d\x89\xc1\x39\x3a\x0f\xdf\x68\x03\xe8\xf2"
      "\x95\xa9\x71\x0f\x6d\xd5\x1d\xba\x50\x3c\x6a\xfe\xcf\xdd\xc4\x98"
      "\xf3\xf2\xe8\x8a\xd6\xca\xfc\xb1\x42\x21\x37\x52\x97\xfb\x8d\x0a"
      "\xe7\x72\x65\xc3\x4a\xf8\x4c\xb8\x04\xdd\x2e\x8e\xcd\xb3\x68\xe1"
      "\xbf\x9c\xd3\xef\x0c\xe0\xda\xff\x9c\x6f\xab\xcc\x97\x53\xfa\xdd"
      "\xd5\x47\xf1\xaa\x89\x9e\xa2\x1a\x5e\xb4\x18\xb3\x3f\xf8\xb8\x49"
      "\x61\x81\xac\xd0\x5a\x7b\x5c\x77\x96\x4e\xd9\x70\x54\x69\x78\xd4"
      "\x4e\xc1\xba\xe5\x0a\xc9\xec\x44\xd6\x00\x66\xe7\xd8\x31\x51\x7f"
      "\x18\xef\xee\x6a\x6c\xb9\x27\x34\xe9\x91\x28\x54\xd4\x39\xf0\x82"
      "\x6d\xa7\x26\x85\x34\x3b\x59\x7a\x2a\x94\xfb\x34\x0d\x84\xae\xc2"
      "\x18\x79\x2d\x4a\xb0\xf9\x62\xdf\x3e\x5e\x71\x13\x6e\x22\xb9\xdb"
      "\x15\xce\xf1\xad\x69\x48\xb3\x61\x27\x83\x7d\xdc\x5b\xdb\x20\x66"
      "\x39\x24\x21\xac\xd6\xac\xca\xfb\x6e\x05\xd6\x1e\x32\xa7\xbf\x81"
      "\x3f\xb3\x18\x8a\x31\xbb\x1e\x67\x21\x93\x4b\xb1\x14\x54\xfd\xfe"
      "\x4e\xaa\x8c\xdc\x12\x02\x72\x14\x8e\x01\xf7\xe8\xbc\x1b\x6c\x6a"
      "\x1b\xe6\xb2\xbd\x69\x5e\x75\x54\xa7\xf0\x3a\x84\x2e\x5a\x65\x4e"
      "\x70\x81\x31\xdd\xde\x36\xaa\x2d\xdd\xed\x8e\x3a\x54\x80\x5a\xac"
      "\xce\x1c\x48\xb9\xc3\x44\x1a\x94\xe0\xb3\x34\x19\xba\x08\x74\x8a"
      "\xf5\x0e\x74\x35\x78\x83\x15\xe2\x41\xba\x4a\x21\xb9\xd9\x03\x01"
      "\x58\x03\x2b\xa6\xc3\x26\xcf\x8e\x8c\x27\x4f\x2d\x59\x0c\xca\xf3"
      "\xa6\xe9\xa1\xaf\x34\x43\x35\x1f\x55\x36\x3a\x6a\x5e\xe5\x41\xf8"
      "\xd5\x18\xe8\x31\x31\xc4\x4e\x66\xe4\x10\x43\x81\x43\xb2\xe7\xab"
      "\xe6\xe6\x3f\x8f\xb3\xd9\xd9\x79\xf6\xc8\xfb\x8f\x6e\xee\xba\x3e"
      "\x43\x5d\x8e\xca\xcb\x05\x34\x43\x2c\xb3\x6b\xc9\xbd\x27\xfe\xcf"
      "\xe6\x38\x86\xdc\x98\xb0\x0f\x13\x92\xf2\x91\x57\x51\xb2\xd2\x5b"
      "\x84\xef\x5c\xd2\xa4\x75\x82\x54\x24\x74\x5a\x4a\xee\x82\x2d\xaa"
      "\x1e\x97\x2e\xae\x77\x75\x6c\x39\x2f\x13\x71\xab\x8e\x19\xbc\x49"
      "\x1a\x14\x1a\xc9\x26\xcd\xc3\x0d\x31\xf2\x7e\x1c\x85\x38\x24\x04"
      "\x60\x54\x2b\xfe\xec\x8b\xbc\xc0\x71\xe6\xc2\x8d\xe1\x82\x8b\xf0"
      "\xae\xed\x06\x7c\x2f\x93\x3d\xfb\x9a\x61\xc3\xac\x96\xf7\x24\x4a"
      "\x69\xc8\x26\x2c\xba\x42\x0c\x11\xf5\x65\x20\x62\x73\x37\x59\xca"
      "\xe9\x50\xe2\xb0\x20\x4c\x79\x90\xe2\x24\xc3\x99\xaa\x79\x0b\x92"
      "\x57\x6f\x91\x96\x3d\xe8\xd5\xb1\x34\x12\xaa\xb9\x43\x6f\xed\xec"
      "\xbc\x7f\xe7\xeb\xab\x73\x52\x5f\x59\x63\x04\x1f\xa2\x6e\x08\x41"
      "\x43\x28\xd1\xdf\xfe\xbc\x76\x27\xa1\x8c\xd3\x30\xc5\xe3\xf7\x31"
      "\xdc\x59\xc2\x95\x86\x71\xcd\x89\xeb\xeb\x76\x93\xcf\xb1\xa0\xa3"
      "\x42\x3e\x34\x24\x77\x1e\x58\x1a\x99\x46\xe1\x8a\xd9\xe9\xad\xdc"
      "\xcb\xdc\x75\x5c\x36\x17\x2a\x92\x5d\x7d\x05\xc9\xee\x68\x3e\x69"
      "\x67\xb8\x89\x7b\x7e\xba\x85\x88\xa0\xf3\xef\xab\x84\x2b\xa5\x7c"
      "\x54\x57\xf6\xac\x65\xd1\x93\x29\xb5\x61\xc7\xcb\x6c\x33\x86\xae"
      "\x31\x2b\xe8\x65\x95\xc8\xb6\x76\x64\x63\x05\x02\xc5\x4b\x32\xe6"
      "\x41\x4c\xfc\xd0\xd4\xe4\x69\x14\xf0\xc0\x80\x5f\x0b\xb9\x94\x92"
      "\xf7\x58\xdf\x68\xb2\x7f\x74\x1e\xc4\xd0\x41\xf1\x9d\xe9\x60\x02"
      "\xf1\x0f\x41\xb8\x4c\x1a\x8f\xcb\xed\x47\xc6\xb1\xa4\x46\x63\x1e"
      "\xcb\xc7\xe5\x75\x44\x82\x44\x5a\x5b\x0a\x62\xd3\x85\xfd\x0d\x72"
      "\xc6\x1b\x3a\x35\xc8\xd9\xd0\x92\xc1\xd7\xcd\x9a\xbf\x33\x01\xa3"
      "\xe0\x9c\x58\x73\x36\x56\xc8\x26\x8d\xc3\xb6\x98\xe5\x87\x79\x91"
      "\xf2\x8f\x4d\x5a\x68\x13\xbd\x37\xa6\xf1\x9a\x2e\xe6\x22\xfa\x71"
      "\x43\x17\x9a\x93\xa9\x82\x2c\xb8\xee\x54\x38\x31\xbc\x64\x54\x20"
      "\x61\x48\x1c\xfa\xde\xf0\x49\xfd\x34\xb1\xee\x06\x94\x63\xd5\x27"
      "\x10\xde\x2b\xbe\x97\x76\x6f\xc1\x65\x2f\x81\x36\xc6\x62\xef\x48"
      "\xf4\x5b\xb2\x02\x9b\x1c\x24\x98\xbb\xed\x3e\xe8\x85\xc3\xe2\x45"
      "\xdb\x69\x35\xd5\x97\xf9\x86\x5c\x8a\xe2\xd4\x33\xaf\x3b\x1c\xbc"
      "\x8a\xf5\xfb\x9d\x83\xec\x73\x00\x0a\xd3\xca\x10\xe5\x3e\x38\x1e"
      "\x5e\xfd\xb9\x54\x92\xe0\x44\x08\x7f\xeb\xb7\x59\x49\x48\x15\x0d"
      "\x85\xb0\x72\x4d\xc0\x99\x4e\x66\x3b\xd5\x0d\xaa\xb4\xf8\xb6\x9a"
      "\x8b\xc9\x8d\x6e\x2f\x7a\xb4\xd5\xe3\x00\x82\x80\xa5\x70\x34\xdf"
      "\xb1\x5c\xd1\xab\x8b\x64\x56\x43\x9e\xb4\x91\x5f\x0e\x90\x3f\xd8"
      "\xd0\xe3\xfc\x31\x13\x0a\x04\xbe\x4b\x2a\x2a\xdf\x44\x4c\xb2\x69"
      "\xab\xe0\x8a\x11\x2c\x01\xe6\x59\x2f\x07\x51\x84\xa4\x85\x94\x46"
      "\xe9\x30\x9f\xf5\x91\x25\x93\x85\x93\xe9\xd6\x35\x9f\x5f\x85\xa6"
      "\x7b\x59\x92\xb1\x7a\x79\xc6\x71\x0d\xc7\xd3\x20\xfa\x84\xcc\xf4"
      "\xab\x4c\xf7\xd2\xe6\xd7\xec\x62\x85\x52\x2f\x1f\x4c\x92\x8e\x85"
      "\x93\x3c\x6f\xfd\xe8\xb9\xaa\xec\x9b\xe7\x0d\xa4\x1b\x13\x31\x97"
      "\x29\x20\x3d\xc5\xd0\xd4\x4d\xec\x4a\x18\x9c\x28\x48\xa3\x6c\x14"
      "\x86\x5d\xe0\xc1\x60\x6d\x90\x5d\xaa\x6c\x70\xbd\x6a\xe0\x68\xb5"
      "\x74\x8c\x46\x09\x86\x9a\xb1\xba\xe4\xf6\x3f\xd0\x88\x1f\x54\x83"
      "\x14\x17\x5b\x5a\x52\xd5\x72\x09\x22\x28\xdb\x18\x2d\xeb\xac\x59"
      "\x10\x1b\x88\x6d\x45\xa7\x2e\x19\xfd\xdc\x4f\xb1\x1f\xde\x8d\xcc"
      "\x95\xbe\x19\x56\x22\x10\x89\x68\x80\x4e\x7c\x7e\xac\xba\xce\x73"
      "\x2b\x1b\x8c\x38\x85\x59\x9d\xa7\x12\xb5\x8c\x0e\x7f\xd3\x2b\xf5"
      "\x9d\x46\xe8\x65\xc8\xe5\x40\x9e\x6b\x84\x0b\x5a\xc7\x52\x89\x59"
      "\x35\x57\x8f\x71\x0a\x37\xc0\xf0\xf3\x0f\x06\xd2\x8e\xab\x2a\x92"
      "\xf3\x4e\x5e\x14\xe0\xfd\x04\xa0\xc1\x5a\x93\x52\x31\x45\x14\x77"
      "\x1d\xe6\x81\x49\xca\xe3\x7f\xf0\x89\x80\x3e\x6a\x49\xbc\x6c\x0b"
      "\xb5\x46\x3f\x32\x48\x3e\x9c\x61\x3b\x50\xf4\x18\x48\x83\xb5\x19"
      "\x22\x35\x5b\x08\xcb\xb2\x89\x87\x4d\x1f\xb3\xd6\xaf\x4a\x02\xe8"
      "\x9e\xe0\xdc\x04\xc7\x25\x4e\x49\xe6\x5a\xb5\x43\x68\x26\x0d\xb6"
      "\xd2\x64\xbe\x27\x79\x30\xf0\x2b\xd5\x13\xca\x99\x6b\x2d\x6a\x0e"
      "\x40\xa7\x1d\xcc\xb7\x4f\xec\xdc\x23\x06\xb1\x3a\xd8\xe1\x24\x86"
      "\xde\x73\xa4\x22\x7c\x5d\xd8\x6f\xbd\xdc\xd9\xab\x8d\x7b\x16\x22"
      "\xa7\x6b\xd8\x8a\xdf\x5f\xa0\x3b\x34\x11\xc9\x40\x6f\xab\xc2\x37"
      "\xdc\x6b\xd2\x25\x44\xa5\xc7\xec\x67\x0c\x3f\xf6\xba\x77\x53\x2e"
      "\xd0\xae\xc2\x0e\xe2\x56\x2d\x72\x92\xb2\x91\xfe\x04\x89\xc3\x34"
      "\x20\x6d\x8a\x92\xb1\x1a\xfc\xff\xcd\xd9\xc0\xc1\xa0\xa7\x7d\x9e"
      "\xe8\x5e\x76\xf1\x81\x03\xdf\xd4\x0b\x98\x0a\x36\xd4\x1a\x50\xd0"
      "\xe3\x2f\x51\xc2\xd8\x4e\xc9\x77\xbc\xb8\x7f\x38\xe3\x00\xdb\x2f"
      "\xbc\x48\x16\x6a\x28\xcf\x56\xd2\x58\x01\xbb\x21\x72\x55\xfa\x3c"
      "\xd3\xc9\x04\x80\xdc\x38\xa6\xa5\xcd\xed\xba\xd1\xbc\xb7\x9a\x7e"
      "\xb4\xe8\x59\x2a\x8d\x2e\xcf\x7c\xdd\x31\xf7\x8b\x96\x71\xf0\x06"
      "\xfb\x29\x23\xf6\x0d\x66\x59\x8e\x82\x95\x8d\x42\x8e\x4e\x01\x9e"
      "\x6d\x19\x83\x04\x36\x3d\xe3\x8a\xc4\x54\x90\x23\xa9\x81\xda\xcb"
      "\x08\x6f\x9a\xd2\x13\x8d\x46\x1c\x4d\xf3\xa9\x3e\x60\x5d\x90\x3b"
      "\xca\x95\x82\x1b\xa2\x1a\x19\xc5\x5c\x5a\xc9\x67\xcf\x65\xe4\x8d"
      "\xb2\x2b\x4e\x0c\x7f\x7b\xfa\x32\x49\x69\xda\x5a\xb4\x9c\x06\xbf"
      "\x12\xa4\x0f\x4a\x8c\xd0\x73\x8e\xdf\x66\x72\xd9\x29\xab\x06\x3a"
      "\xf1\x3c\xd8\x30\xd6\xbb\x0e\x37\x07\x4e\xe5\xf6\x87\x8a\x4a\xd0"
      "\x66\x68\x84\xd1\x23\x62\xb6\x07\x77\x0e\x60\x7d\x30\x22\xc2\xff"
      "\x53\x46\x60\x69\xb0\x73\xe5\x33\x25\x0b\x47\x68\xa0\xf4\x52\x3d"
      "\x91\x6e\x1c\x4d\x9e\x0a\x16\xd5\xb3\x3b\x2d\x3a\x7a\x87\x6c\xfe"
      "\x7b\xc8\x81\xa8\xe6\xce\xb9\xb3\xc5\xc2\xd1\xde\x90\x92\x0f\x57"
      "\x71\x90\x6a\x73\x4b\x5b\x07\x97\xe6\xda\x7d\xdb\xd5\xd1\x3e\xa6"
      "\xbf\x26\x23\x46\xc6\xcf\xef\x2a\xed\xa7\xc0\x52\xda\x40\x2e\xd6"
      "\x2e\xc4\xf1\xb2\x2f\x69\xac\x73\xe4\x2d\x75\xea\x19\x4c\xb5\x50"
      "\xbc\x03\x51\x9c\x05\xda\x8a\x3b\xc9\x98\xd2\x43\x40\xc6\xd9\x0f"
      "\x53\x2e\x24\x56\x55\x4e\x41\xc9\xcd\xa9\x06\xe8\xbc\x69\x10\xaa"
      "\x99\x3d\x56\x9e\xd2\xbc\x48\xcd\x58\x2d\xe3\x16\x6a\x23\x3d\x85"
      "\xc5\x14\x80\x46\x07\x96\xcf\xd9\xdc\xff\x14\x39\xfd\x5c\xc2\x2d"
      "\xb9\xf9\x51\x09\x5d\xd3\xe4\xf6\x3f\x51\x62\x10\xf6\xd4\x76\x78"
      "\x11\xf0\xd5\x63\xb8\x53\x2b\xb2\xa0\x58\x4e\x71\x90\xea\xb6\xc6"
      "\x92\x59\x06\x8d\x53\x63\x0a\x0c\xd4\x62\x2d\x57\x12\xf9\xf8\xd8"
      "\xdb\x10\x40\x2e\x09\x83\x1b\xbb\x8c\xdd\xbc\x0c\xa0\xc8\x14\x23"
      "\xa5\x93\xed\xd9\x2d\x0b\xc0\xfd\x0e\x1d\xd1\xbb\x95\x96\xb6\xbc"
      "\x81\x31\x6f\x20\x6f\x72\x1c\x4a\x87\xfb\x66\x2d\x79\x3c\xa4\x6d"
      "\x05\xc1\x71\x50\x83\xad\xea\x03\x26\x2b\xe4\x10\xc8\x33\x0b\x61"
      "\xdf\x30\x4b\x27\x8f\xfe\xbd\xcc\x8d\xda\x4f\xaf\x8f\xad\xaa\x25"
      "\xa1\x50\x95\x95\x7d\x8e\x35\xec\xe8\x7e\xd4\x98\x68\xe4\x95\xac"
      "\xa6\x98\x95\x38\xf8\xd2\xab\xdc\xb9\x77\xfc\xa9\xbf\xb5\x18\xed"
      "\xca\x15\xb2\xe7\xd0\x23\xcb\xc4\x73\xc0\x85\x0b\x57\xeb\xf4\xe6"
      "\x11\x97\xb1\x03\xa6\x66\x0a\x24\x3b\xb6\xe8\x2f\xfe\x9c\x78\x0a"
      "\x42\x01\xe9\x35\x58\xf7\x55\x13\x80\x24\x23\x30\x62\x6c\x7b\x86"
      "\xff\x7e\x12\x34\xf3\x33\x4c\x1c\xed\x5a\x96\xd6\xcd\x04\xfb\xf9"
      "\x7c\xde\xc0\xd5\x70\x52\x4e\x0f\xa2\x8e\x6b\xa6\x8f\x3a\x08\xf9"
      "\x08\x0f\x2f\xd7\xa2\xb1\x91\x53\x65\x63\x63\xb8\x31\xba\xf4\x21"
      "\xb5\x17\xd7\x59\x94\xd0\x0e\x8c\x91\x5c\x37\xf8\x3a\xd8\x8c\x7f"
      "\x76\xd0\x63\x7a\xd9\xb4\xa6\x3d\xf8\xfb\x72\xd5\x65\xf0\x10\x4a"
      "\x42\x15\x70\xb1\x9b\x5f\xf8\xf9\x9f\x5b\x29\x0a\x28\x2a\x68\x6b"
      "\xaf\xec\x84\x94\xbc\x22\xdf\xe8\x3e\xcb\xee\xc3\xc8\x03\x00\xf3"
      "\x02\xff\x07\x4d\x95\x62\x12\x9e\x51\x1a\x20\x4a\x5a\xa2\x66\x81"
      "\x3d\x29\x98\x23\x17\x11\x95\x84\x51\x9f\x40\x7a\x3d\x6f\x61\xbe"
      "\x2b\x1b\x03\x82\xad\xb6\x8f\x69\x3d\x31\x39\xc7\x8b\x0a\x77\x6e"
      "\x02\x88\xdd\x13\x6a\x9c\x72\x46\x5d\xf0\x92\xb4\x76\xac\xc0\xbd"
      "\x8d\x2e\x3c\xcb\xa3\x89\x31\x07\x36\x68\x35\x03\x4c\x95\x6d"
      "\xbd",
      4096);
  r[18] = syscall(SYS_writev, r[2], 0x20013ffeul, 0x5ul, 0, 0, 0);
  return 0;
}

On commit 34229b277480f46c1e9a19f027f30b074512e68b.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
  2016-02-03  8:57 ` Dmitry Vyukov
@ 2016-02-03  9:35   ` Takashi Iwai
  -1 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03  9:35 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, 03 Feb 2016 09:57:50 +0100,
Dmitry Vyukov wrote:
> 
> Hello,
> 
> The following program triggers an out-of-bounds write in
> snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> its way.

What card is /dev/midi3?  Please check /proc/asound/cards.
Is it MTPAV?


Takashi

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
@ 2016-02-03  9:35   ` Takashi Iwai
  0 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03  9:35 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, LKML, Kostya Serebryany, syzkaller,
	Alexander Potapenko, Sasha Levin

On Wed, 03 Feb 2016 09:57:50 +0100,
Dmitry Vyukov wrote:
> 
> Hello,
> 
> The following program triggers an out-of-bounds write in
> snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> its way.

What card is /dev/midi3?  Please check /proc/asound/cards.
Is it MTPAV?


Takashi

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
  2016-02-03  9:35   ` Takashi Iwai
@ 2016-02-03  9:41     ` Takashi Iwai
  -1 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03  9:41 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, 03 Feb 2016 10:35:14 +0100,
Takashi Iwai wrote:
> 
> On Wed, 03 Feb 2016 09:57:50 +0100,
> Dmitry Vyukov wrote:
> > 
> > Hello,
> > 
> > The following program triggers an out-of-bounds write in
> > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> > its way.
> 
> What card is /dev/midi3?  Please check /proc/asound/cards.
> Is it MTPAV?

In anyway the patch below should paper over it.  But it's still
strange that it gets a negative value there.  Could you put

   WARN_ON(count1 < 0)

before the newly added check?

I tried it locally with virmidi but it didn't appear, so far.  Maybe
my setup is too slow and has fewer CPUs than yours.


thanks,

Takashi

---
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 26ca02248885..2fef77d9de50 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1239,6 +1239,8 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 	}
 	while (count > 0 && runtime->avail > 0) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
+		if (count1 <= 0)
+			break;
 		if (count1 > count)
 			count1 = count;
 		if (count1 > (long)runtime->avail)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
@ 2016-02-03  9:41     ` Takashi Iwai
  0 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03  9:41 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, 03 Feb 2016 10:35:14 +0100,
Takashi Iwai wrote:
> 
> On Wed, 03 Feb 2016 09:57:50 +0100,
> Dmitry Vyukov wrote:
> > 
> > Hello,
> > 
> > The following program triggers an out-of-bounds write in
> > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> > its way.
> 
> What card is /dev/midi3?  Please check /proc/asound/cards.
> Is it MTPAV?

In anyway the patch below should paper over it.  But it's still
strange that it gets a negative value there.  Could you put

   WARN_ON(count1 < 0)

before the newly added check?

I tried it locally with virmidi but it didn't appear, so far.  Maybe
my setup is too slow and has fewer CPUs than yours.


thanks,

Takashi

---
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 26ca02248885..2fef77d9de50 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1239,6 +1239,8 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 	}
 	while (count > 0 && runtime->avail > 0) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
+		if (count1 <= 0)
+			break;
 		if (count1 > count)
 			count1 = count;
 		if (count1 > (long)runtime->avail)

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
  2016-02-03  9:41     ` Takashi Iwai
@ 2016-02-03 11:39       ` Takashi Iwai
  -1 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03 11:39 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, 03 Feb 2016 10:41:14 +0100,
Takashi Iwai wrote:
> 
> On Wed, 03 Feb 2016 10:35:14 +0100,
> Takashi Iwai wrote:
> > 
> > On Wed, 03 Feb 2016 09:57:50 +0100,
> > Dmitry Vyukov wrote:
> > > 
> > > Hello,
> > > 
> > > The following program triggers an out-of-bounds write in
> > > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> > > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> > > its way.
> > 
> > What card is /dev/midi3?  Please check /proc/asound/cards.
> > Is it MTPAV?
> 
> In anyway the patch below should paper over it.  But it's still
> strange that it gets a negative value there.  Could you put
> 
>    WARN_ON(count1 < 0)
> 
> before the newly added check?
> 
> I tried it locally with virmidi but it didn't appear, so far.  Maybe
> my setup is too slow and has fewer CPUs than yours.

Scratch my previous patch, I could reproduce the issue on a faster
machine in my office now :)  Will work on it.


Takashi

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
@ 2016-02-03 11:39       ` Takashi Iwai
  0 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03 11:39 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, LKML, Kostya Serebryany, syzkaller,
	Alexander Potapenko, Sasha Levin

On Wed, 03 Feb 2016 10:41:14 +0100,
Takashi Iwai wrote:
> 
> On Wed, 03 Feb 2016 10:35:14 +0100,
> Takashi Iwai wrote:
> > 
> > On Wed, 03 Feb 2016 09:57:50 +0100,
> > Dmitry Vyukov wrote:
> > > 
> > > Hello,
> > > 
> > > The following program triggers an out-of-bounds write in
> > > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> > > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> > > its way.
> > 
> > What card is /dev/midi3?  Please check /proc/asound/cards.
> > Is it MTPAV?
> 
> In anyway the patch below should paper over it.  But it's still
> strange that it gets a negative value there.  Could you put
> 
>    WARN_ON(count1 < 0)
> 
> before the newly added check?
> 
> I tried it locally with virmidi but it didn't appear, so far.  Maybe
> my setup is too slow and has fewer CPUs than yours.

Scratch my previous patch, I could reproduce the issue on a faster
machine in my office now :)  Will work on it.


Takashi

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
  2016-02-03 11:39       ` Takashi Iwai
@ 2016-02-03 12:02         ` Takashi Iwai
  -1 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03 12:02 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, 03 Feb 2016 12:39:31 +0100,
Takashi Iwai wrote:
> 
> On Wed, 03 Feb 2016 10:41:14 +0100,
> Takashi Iwai wrote:
> > 
> > On Wed, 03 Feb 2016 10:35:14 +0100,
> > Takashi Iwai wrote:
> > > 
> > > On Wed, 03 Feb 2016 09:57:50 +0100,
> > > Dmitry Vyukov wrote:
> > > > 
> > > > Hello,
> > > > 
> > > > The following program triggers an out-of-bounds write in
> > > > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> > > > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> > > > its way.
> > > 
> > > What card is /dev/midi3?  Please check /proc/asound/cards.
> > > Is it MTPAV?
> > 
> > In anyway the patch below should paper over it.  But it's still
> > strange that it gets a negative value there.  Could you put
> > 
> >    WARN_ON(count1 < 0)
> > 
> > before the newly added check?
> > 
> > I tried it locally with virmidi but it didn't appear, so far.  Maybe
> > my setup is too slow and has fewer CPUs than yours.
> 
> Scratch my previous patch, I could reproduce the issue on a faster
> machine in my office now :)  Will work on it.

This turned out to be a race in updates of runtime->appl_ptr & co.
We do temporary spin unlock and relock while copying the user-space
data, and then update these values.  Meanwhile these values are
referred as the position to copy, and the concurrent accesses may lead
to the negative value.

Below is a quick fix for that, just updating these before the
temporary unlock.

The patch also fixes the read size where it has more race problems...

It seems working on my machine.  Let me know if this works for you,
too.  Then I'll cook up the official patch.


thanks,

Takashi

---
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 26ca02248885..795437b10082 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -942,31 +942,36 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
 	unsigned long flags;
 	long result = 0, count1;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
+	spin_lock_irqsave(&runtime->lock, flags);
 	while (count > 0 && runtime->avail) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
 		if (count1 > count)
 			count1 = count;
-		spin_lock_irqsave(&runtime->lock, flags);
 		if (count1 > (int)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
+			memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
 		if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
 			if (copy_to_user(userbuf + result,
-					 runtime->buffer + runtime->appl_ptr, count1)) {
+					 runtime->buffer + appl_ptr, count1)) {
 				return result > 0 ? result : -EFAULT;
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
-		spin_unlock_irqrestore(&runtime->lock, flags);
 		result += count1;
 		count -= count1;
 	}
+	spin_unlock_irqrestore(&runtime->lock, flags);
 	return result;
 }
 
@@ -1223,6 +1228,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 	unsigned long flags;
 	long count1, result;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
 	if (!kernelbuf && !userbuf)
 		return -EINVAL;
@@ -1243,12 +1249,19 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 			count1 = count;
 		if (count1 > (long)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(runtime->buffer + runtime->appl_ptr,
+			memcpy(runtime->buffer + appl_ptr,
 			       kernelbuf + result, count1);
 		else if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
-			if (copy_from_user(runtime->buffer + runtime->appl_ptr,
+			if (copy_from_user(runtime->buffer + appl_ptr,
 					   userbuf + result, count1)) {
 				spin_lock_irqsave(&runtime->lock, flags);
 				result = result > 0 ? result : -EFAULT;
@@ -1256,9 +1269,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
 		result += count1;
 		count -= count1;
 	}

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
@ 2016-02-03 12:02         ` Takashi Iwai
  0 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03 12:02 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, 03 Feb 2016 12:39:31 +0100,
Takashi Iwai wrote:
> 
> On Wed, 03 Feb 2016 10:41:14 +0100,
> Takashi Iwai wrote:
> > 
> > On Wed, 03 Feb 2016 10:35:14 +0100,
> > Takashi Iwai wrote:
> > > 
> > > On Wed, 03 Feb 2016 09:57:50 +0100,
> > > Dmitry Vyukov wrote:
> > > > 
> > > > Hello,
> > > > 
> > > > The following program triggers an out-of-bounds write in
> > > > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> > > > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> > > > its way.
> > > 
> > > What card is /dev/midi3?  Please check /proc/asound/cards.
> > > Is it MTPAV?
> > 
> > In anyway the patch below should paper over it.  But it's still
> > strange that it gets a negative value there.  Could you put
> > 
> >    WARN_ON(count1 < 0)
> > 
> > before the newly added check?
> > 
> > I tried it locally with virmidi but it didn't appear, so far.  Maybe
> > my setup is too slow and has fewer CPUs than yours.
> 
> Scratch my previous patch, I could reproduce the issue on a faster
> machine in my office now :)  Will work on it.

This turned out to be a race in updates of runtime->appl_ptr & co.
We do temporary spin unlock and relock while copying the user-space
data, and then update these values.  Meanwhile these values are
referred as the position to copy, and the concurrent accesses may lead
to the negative value.

Below is a quick fix for that, just updating these before the
temporary unlock.

The patch also fixes the read size where it has more race problems...

It seems working on my machine.  Let me know if this works for you,
too.  Then I'll cook up the official patch.


thanks,

Takashi

---
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 26ca02248885..795437b10082 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -942,31 +942,36 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
 	unsigned long flags;
 	long result = 0, count1;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
+	spin_lock_irqsave(&runtime->lock, flags);
 	while (count > 0 && runtime->avail) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
 		if (count1 > count)
 			count1 = count;
-		spin_lock_irqsave(&runtime->lock, flags);
 		if (count1 > (int)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
+			memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
 		if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
 			if (copy_to_user(userbuf + result,
-					 runtime->buffer + runtime->appl_ptr, count1)) {
+					 runtime->buffer + appl_ptr, count1)) {
 				return result > 0 ? result : -EFAULT;
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
-		spin_unlock_irqrestore(&runtime->lock, flags);
 		result += count1;
 		count -= count1;
 	}
+	spin_unlock_irqrestore(&runtime->lock, flags);
 	return result;
 }
 
@@ -1223,6 +1228,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 	unsigned long flags;
 	long count1, result;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
 	if (!kernelbuf && !userbuf)
 		return -EINVAL;
@@ -1243,12 +1249,19 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 			count1 = count;
 		if (count1 > (long)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(runtime->buffer + runtime->appl_ptr,
+			memcpy(runtime->buffer + appl_ptr,
 			       kernelbuf + result, count1);
 		else if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
-			if (copy_from_user(runtime->buffer + runtime->appl_ptr,
+			if (copy_from_user(runtime->buffer + appl_ptr,
 					   userbuf + result, count1)) {
 				spin_lock_irqsave(&runtime->lock, flags);
 				result = result > 0 ? result : -EFAULT;
@@ -1256,9 +1269,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
 		result += count1;
 		count -= count1;
 	}

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
  2016-02-03  9:35   ` Takashi Iwai
  (?)
  (?)
@ 2016-02-03 13:25   ` Dmitry Vyukov
  -1 siblings, 0 replies; 13+ messages in thread
From: Dmitry Vyukov @ 2016-02-03 13:25 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, Feb 3, 2016 at 10:35 AM, Takashi Iwai <tiwai@suse.de> wrote:
> On Wed, 03 Feb 2016 09:57:50 +0100,
> Dmitry Vyukov wrote:
>>
>> Hello,
>>
>> The following program triggers an out-of-bounds write in
>> snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
>> copy -1 bytes (aka 4GB) from user space into kernel smashing all on
>> its way.
>
> What card is /dev/midi3?  Please check /proc/asound/cards.
> Is it MTPAV?

Yes, it was MTPAV. There is only generic code in the stack traces, so
I though it may be a generic issue. Though, of course, the driver
could mess things already.
I've dropped CONFIG_SND_MTPAV now.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
  2016-02-03 12:02         ` Takashi Iwai
  (?)
@ 2016-02-03 13:37         ` Dmitry Vyukov
  2016-02-03 14:26           ` Takashi Iwai
  -1 siblings, 1 reply; 13+ messages in thread
From: Dmitry Vyukov @ 2016-02-03 13:37 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, Feb 3, 2016 at 1:02 PM, Takashi Iwai <tiwai@suse.de> wrote:
> On Wed, 03 Feb 2016 12:39:31 +0100,
> Takashi Iwai wrote:
>>
>> On Wed, 03 Feb 2016 10:41:14 +0100,
>> Takashi Iwai wrote:
>> >
>> > On Wed, 03 Feb 2016 10:35:14 +0100,
>> > Takashi Iwai wrote:
>> > >
>> > > On Wed, 03 Feb 2016 09:57:50 +0100,
>> > > Dmitry Vyukov wrote:
>> > > >
>> > > > Hello,
>> > > >
>> > > > The following program triggers an out-of-bounds write in
>> > > > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
>> > > > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
>> > > > its way.
>> > >
>> > > What card is /dev/midi3?  Please check /proc/asound/cards.
>> > > Is it MTPAV?
>> >
>> > In anyway the patch below should paper over it.  But it's still
>> > strange that it gets a negative value there.  Could you put
>> >
>> >    WARN_ON(count1 < 0)
>> >
>> > before the newly added check?
>> >
>> > I tried it locally with virmidi but it didn't appear, so far.  Maybe
>> > my setup is too slow and has fewer CPUs than yours.
>>
>> Scratch my previous patch, I could reproduce the issue on a faster
>> machine in my office now :)  Will work on it.
>
> This turned out to be a race in updates of runtime->appl_ptr & co.
> We do temporary spin unlock and relock while copying the user-space
> data, and then update these values.  Meanwhile these values are
> referred as the position to copy, and the concurrent accesses may lead
> to the negative value.
>
> Below is a quick fix for that, just updating these before the
> temporary unlock.
>
> The patch also fixes the read size where it has more race problems...
>
> It seems working on my machine.  Let me know if this works for you,
> too.  Then I'll cook up the official patch.


Yes, it fixes the crash for me.  Thanks!


> ---
> diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
> index 26ca02248885..795437b10082 100644
> --- a/sound/core/rawmidi.c
> +++ b/sound/core/rawmidi.c
> @@ -942,31 +942,36 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
>         unsigned long flags;
>         long result = 0, count1;
>         struct snd_rawmidi_runtime *runtime = substream->runtime;
> +       unsigned long appl_ptr;
>
> +       spin_lock_irqsave(&runtime->lock, flags);
>         while (count > 0 && runtime->avail) {
>                 count1 = runtime->buffer_size - runtime->appl_ptr;
>                 if (count1 > count)
>                         count1 = count;
> -               spin_lock_irqsave(&runtime->lock, flags);
>                 if (count1 > (int)runtime->avail)
>                         count1 = runtime->avail;
> +
> +               /* update runtime->appl_ptr before unlocking for userbuf */
> +               appl_ptr = runtime->appl_ptr;
> +               runtime->appl_ptr += count1;
> +               runtime->appl_ptr %= runtime->buffer_size;
> +               runtime->avail -= count1;
> +
>                 if (kernelbuf)
> -                       memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
> +                       memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
>                 if (userbuf) {
>                         spin_unlock_irqrestore(&runtime->lock, flags);
>                         if (copy_to_user(userbuf + result,
> -                                        runtime->buffer + runtime->appl_ptr, count1)) {
> +                                        runtime->buffer + appl_ptr, count1)) {
>                                 return result > 0 ? result : -EFAULT;
>                         }
>                         spin_lock_irqsave(&runtime->lock, flags);
>                 }
> -               runtime->appl_ptr += count1;
> -               runtime->appl_ptr %= runtime->buffer_size;
> -               runtime->avail -= count1;
> -               spin_unlock_irqrestore(&runtime->lock, flags);
>                 result += count1;
>                 count -= count1;
>         }
> +       spin_unlock_irqrestore(&runtime->lock, flags);
>         return result;
>  }
>
> @@ -1223,6 +1228,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
>         unsigned long flags;
>         long count1, result;
>         struct snd_rawmidi_runtime *runtime = substream->runtime;
> +       unsigned long appl_ptr;
>
>         if (!kernelbuf && !userbuf)
>                 return -EINVAL;
> @@ -1243,12 +1249,19 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
>                         count1 = count;
>                 if (count1 > (long)runtime->avail)
>                         count1 = runtime->avail;
> +
> +               /* update runtime->appl_ptr before unlocking for userbuf */
> +               appl_ptr = runtime->appl_ptr;
> +               runtime->appl_ptr += count1;
> +               runtime->appl_ptr %= runtime->buffer_size;
> +               runtime->avail -= count1;
> +
>                 if (kernelbuf)
> -                       memcpy(runtime->buffer + runtime->appl_ptr,
> +                       memcpy(runtime->buffer + appl_ptr,
>                                kernelbuf + result, count1);
>                 else if (userbuf) {
>                         spin_unlock_irqrestore(&runtime->lock, flags);
> -                       if (copy_from_user(runtime->buffer + runtime->appl_ptr,
> +                       if (copy_from_user(runtime->buffer + appl_ptr,
>                                            userbuf + result, count1)) {
>                                 spin_lock_irqsave(&runtime->lock, flags);
>                                 result = result > 0 ? result : -EFAULT;
> @@ -1256,9 +1269,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
>                         }
>                         spin_lock_irqsave(&runtime->lock, flags);
>                 }
> -               runtime->appl_ptr += count1;
> -               runtime->appl_ptr %= runtime->buffer_size;
> -               runtime->avail -= count1;
>                 result += count1;
>                 count -= count1;
>         }

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: sound: out-of-bounds write in snd_rawmidi_kernel_write1
  2016-02-03 13:37         ` Dmitry Vyukov
@ 2016-02-03 14:26           ` Takashi Iwai
  0 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2016-02-03 14:26 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: alsa-devel, Jaroslav Kysela, LKML, Alexander Potapenko,
	Kostya Serebryany, syzkaller, Sasha Levin

On Wed, 03 Feb 2016 14:37:17 +0100,
Dmitry Vyukov wrote:
> 
> On Wed, Feb 3, 2016 at 1:02 PM, Takashi Iwai <tiwai@suse.de> wrote:
> > On Wed, 03 Feb 2016 12:39:31 +0100,
> > Takashi Iwai wrote:
> >>
> >> On Wed, 03 Feb 2016 10:41:14 +0100,
> >> Takashi Iwai wrote:
> >> >
> >> > On Wed, 03 Feb 2016 10:35:14 +0100,
> >> > Takashi Iwai wrote:
> >> > >
> >> > > On Wed, 03 Feb 2016 09:57:50 +0100,
> >> > > Dmitry Vyukov wrote:
> >> > > >
> >> > > > Hello,
> >> > > >
> >> > > > The following program triggers an out-of-bounds write in
> >> > > > snd_rawmidi_kernel_write1 (run in parallel loop). It seems to try to
> >> > > > copy -1 bytes (aka 4GB) from user space into kernel smashing all on
> >> > > > its way.
> >> > >
> >> > > What card is /dev/midi3?  Please check /proc/asound/cards.
> >> > > Is it MTPAV?
> >> >
> >> > In anyway the patch below should paper over it.  But it's still
> >> > strange that it gets a negative value there.  Could you put
> >> >
> >> >    WARN_ON(count1 < 0)
> >> >
> >> > before the newly added check?
> >> >
> >> > I tried it locally with virmidi but it didn't appear, so far.  Maybe
> >> > my setup is too slow and has fewer CPUs than yours.
> >>
> >> Scratch my previous patch, I could reproduce the issue on a faster
> >> machine in my office now :)  Will work on it.
> >
> > This turned out to be a race in updates of runtime->appl_ptr & co.
> > We do temporary spin unlock and relock while copying the user-space
> > data, and then update these values.  Meanwhile these values are
> > referred as the position to copy, and the concurrent accesses may lead
> > to the negative value.
> >
> > Below is a quick fix for that, just updating these before the
> > temporary unlock.
> >
> > The patch also fixes the read size where it has more race problems...
> >
> > It seems working on my machine.  Let me know if this works for you,
> > too.  Then I'll cook up the official patch.
> 
> 
> Yes, it fixes the crash for me.  Thanks!

Great, I'll queue the fix.  FWIW, below is the final form I'm going to
push.


thanks,

Takashi

-- 8< --
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] ALSA: rawmidi: Fix race at copying & updating the position

The rawmidi read and write functions manage runtime stream status
such as runtime->appl_ptr and runtime->avail.  These point where to
copy the new data and how many bytes have been copied (or to be
read).  The problem is that rawmidi read/write call copy_from_user()
or copy_to_user(), and the runtime spinlock is temporarily unlocked
and relocked while copying user-space.  Since the current code
advances and updates the runtime status after the spin unlock/relock,
the copy and the update may be asynchronous, and eventually
runtime->avail might go to a negative value when many concurrent
accesses are done.  This may lead to memory corruption in the end.

For fixing this race, in this patch, the status update code is
performed in the same lock before the temporary unlock.  Also, the
spinlock is now taken more widely in snd_rawmidi_kernel_read1() for
protecting more properly during the whole operation.

BugLink: http://lkml.kernel.org/r/CACT4Y+b-dCmNf1GpgPKfDO0ih+uZCL2JV4__j-r1kdhPLSgQCQ@mail.gmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/rawmidi.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 26ca02248885..795437b10082 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -942,31 +942,36 @@ static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
 	unsigned long flags;
 	long result = 0, count1;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
+	spin_lock_irqsave(&runtime->lock, flags);
 	while (count > 0 && runtime->avail) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
 		if (count1 > count)
 			count1 = count;
-		spin_lock_irqsave(&runtime->lock, flags);
 		if (count1 > (int)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(kernelbuf + result, runtime->buffer + runtime->appl_ptr, count1);
+			memcpy(kernelbuf + result, runtime->buffer + appl_ptr, count1);
 		if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
 			if (copy_to_user(userbuf + result,
-					 runtime->buffer + runtime->appl_ptr, count1)) {
+					 runtime->buffer + appl_ptr, count1)) {
 				return result > 0 ? result : -EFAULT;
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
-		spin_unlock_irqrestore(&runtime->lock, flags);
 		result += count1;
 		count -= count1;
 	}
+	spin_unlock_irqrestore(&runtime->lock, flags);
 	return result;
 }
 
@@ -1223,6 +1228,7 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 	unsigned long flags;
 	long count1, result;
 	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	unsigned long appl_ptr;
 
 	if (!kernelbuf && !userbuf)
 		return -EINVAL;
@@ -1243,12 +1249,19 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 			count1 = count;
 		if (count1 > (long)runtime->avail)
 			count1 = runtime->avail;
+
+		/* update runtime->appl_ptr before unlocking for userbuf */
+		appl_ptr = runtime->appl_ptr;
+		runtime->appl_ptr += count1;
+		runtime->appl_ptr %= runtime->buffer_size;
+		runtime->avail -= count1;
+
 		if (kernelbuf)
-			memcpy(runtime->buffer + runtime->appl_ptr,
+			memcpy(runtime->buffer + appl_ptr,
 			       kernelbuf + result, count1);
 		else if (userbuf) {
 			spin_unlock_irqrestore(&runtime->lock, flags);
-			if (copy_from_user(runtime->buffer + runtime->appl_ptr,
+			if (copy_from_user(runtime->buffer + appl_ptr,
 					   userbuf + result, count1)) {
 				spin_lock_irqsave(&runtime->lock, flags);
 				result = result > 0 ? result : -EFAULT;
@@ -1256,9 +1269,6 @@ static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
 			}
 			spin_lock_irqsave(&runtime->lock, flags);
 		}
-		runtime->appl_ptr += count1;
-		runtime->appl_ptr %= runtime->buffer_size;
-		runtime->avail -= count1;
 		result += count1;
 		count -= count1;
 	}
-- 
2.7.0

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-02-03 14:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-03  8:57 sound: out-of-bounds write in snd_rawmidi_kernel_write1 Dmitry Vyukov
2016-02-03  8:57 ` Dmitry Vyukov
2016-02-03  9:35 ` Takashi Iwai
2016-02-03  9:35   ` Takashi Iwai
2016-02-03  9:41   ` Takashi Iwai
2016-02-03  9:41     ` Takashi Iwai
2016-02-03 11:39     ` Takashi Iwai
2016-02-03 11:39       ` Takashi Iwai
2016-02-03 12:02       ` Takashi Iwai
2016-02-03 12:02         ` Takashi Iwai
2016-02-03 13:37         ` Dmitry Vyukov
2016-02-03 14:26           ` Takashi Iwai
2016-02-03 13:25   ` Dmitry Vyukov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.