sound: uninterruptible hang in snd_seq_oss_writeq_sync

From: Dmitry Vyukov
Date: Tue Mar 01 2016 - 07:33:53 EST


Hello,

The following program creates an unkillable process:

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

#ifndef SYS_mmap
#define SYS_mmap 9
#endif
#ifndef SYS_syz_open_dev
#define SYS_syz_open_dev 1000001
#endif
#ifndef SYS_write
#define SYS_write 1
#endif
#ifndef SYS_read
#define SYS_read 0
#endif
#ifndef SYS_sync_file_range
#define SYS_sync_file_range 277
#endif

long r[61];

int main()
{
memset(r, -1, sizeof(r));
r[0] = syscall(SYS_mmap, 0x20000000ul, 0x5e000ul, 0x3ul, 0x32ul,
0xfffffffffffffffful, 0x0ul);
r[2] = syscall(SYS_open, "/dev/sequencer", 0x202ul, 0, 0, 0);
*(uint8_t*)0x20057000 = (uint8_t)0x7;
*(uint8_t*)0x20057001 = (uint8_t)0x6;
*(uint8_t*)0x20057002 = (uint8_t)0x3;
*(uint8_t*)0x20057003 = (uint8_t)0x99be;
*(uint32_t*)0x2005700c = (uint32_t)0x4;
*(uint8_t*)0x20057010 = (uint8_t)0x5;
*(uint8_t*)0x20057011 = (uint8_t)0xffffffffffffffff;
*(uint8_t*)0x20057012 = (uint8_t)0x100;
*(uint8_t*)0x20057013 = (uint8_t)0x1;
*(uint8_t*)0x20057024 = (uint8_t)0x8;
*(uint8_t*)0x20057025 = (uint8_t)0xabe4;
*(uint16_t*)0x20057026 = (uint16_t)0x3;
*(uint64_t*)0x20057028 = (uint64_t)0x2005055c;
*(uint8_t*)0x20057030 = (uint8_t)0xffffffffffffffe0;
*(uint8_t*)0x20057031 = (uint8_t)0xffffffffffffffb8;
*(uint8_t*)0x20057032 = (uint8_t)0x8;
*(uint8_t*)0x20057033 = (uint8_t)0x7;
*(uint32_t*)0x2005703c = (uint32_t)0x5;
*(uint8_t*)0x20057040 = (uint8_t)0x5;
*(uint8_t*)0x20057041 = (uint8_t)0x401;
*(uint8_t*)0x20057042 = (uint8_t)0x8;
*(uint8_t*)0x20057043 = (uint8_t)0x4;
*(uint8_t*)0x2005704c = (uint8_t)0x0;
*(uint8_t*)0x2005704d = (uint8_t)0x3;
*(uint8_t*)0x2005704e = (uint8_t)0x200;
*(uint8_t*)0x2005704f = (uint8_t)0xee;
*(uint8_t*)0x20057050 = (uint8_t)0x2;
*(uint8_t*)0x20057051 = (uint8_t)0x8;
*(uint8_t*)0x20057052 = (uint8_t)0x800;
*(uint8_t*)0x20057053 = (uint8_t)0xfffffffffffff000;
*(uint64_t*)0x20057068 = (uint64_t)0x77359400;
*(uint64_t*)0x20057070 = (uint64_t)0x0;
*(uint8_t*)0x20057078 = (uint8_t)0x10000;
*(uint8_t*)0x20057079 = (uint8_t)0x946;
*(uint8_t*)0x2005707a = (uint8_t)0x1;
*(uint8_t*)0x2005707b = (uint8_t)0x1ff;
*(uint8_t*)0x2005708c = (uint8_t)0x3;
*(uint32_t*)0x20057090 = (uint32_t)0x7;
*(uint32_t*)0x20057094 = (uint32_t)0x1;
*(uint8_t*)0x20057098 = (uint8_t)0x2;
*(uint8_t*)0x20057099 = (uint8_t)0x7ff;
*(uint8_t*)0x2005709a = (uint8_t)0x8;
*(uint8_t*)0x2005709b = (uint8_t)0xdd8;
*(uint64_t*)0x200570b0 = (uint64_t)0x1;
*(uint64_t*)0x200570b8 = (uint64_t)0x0;
*(uint8_t*)0x200570c0 = (uint8_t)0x9;
*(uint8_t*)0x200570c1 = (uint8_t)0x3;
*(uint8_t*)0x200570c2 = (uint8_t)0x7ff;
*(uint8_t*)0x200570c3 = (uint8_t)0x8;
*(uint32_t*)0x200570d4 = (uint32_t)0xec;
*(uint64_t*)0x200570d8 = (uint64_t)0x20053f14;
memcpy((void*)0x2005055c,
"\xa4\x62\xd2\xb0\x88\xe0\x2b\xbd\xea\xa1\xa5\xf7\x7b\x89\xca"
"\xb0\x43\xca\x19\x6d\x70\xb6\xa6\xcd\x30\xaa\x98\x07\xb3\xf3"
"\xea\xf8\x44\x19\xc8\x83\xbc\xb7\x33\xd1\xd0\x5e\x8f\x34\x12"
"\x82\xb4\xf8\xbd\x02\x63\x0b\xe7\x45\x23\x40\xa4\x51\x40\x23"
"\x01\xcc\x57\x89\x40\x9c\xc1\x29\x36\xe2\xc0\x70\xe5\xda\xc9"
"\x1f\x40\x25\xe0\x74\x98\x07\x75\xe9\x5a\xfc\x0e\x10\x3f\xd9"
"\x4b\xc3\xc2\x48\xfa\x18\xb8\xda\x49\x3e\xeb\x69\x2c\x4b\xd2"
"\xb7\xac\xc6\x5a\x1c\xfd",
111);
memcpy((void*)0x20053f14,
"\x1b\x4b\xa5\x94\xeb\xe1\xd9\x4b\x57\xf2\xeb\xab\xdd\xe5\xba"
"\x24\xf2\xc8\x36\x90\x88\x21\x2c\xec\x8e\x5a\x0d\x24\x0f\x48"
"\xcc\x0d\x3c\xab\x21\x8e\xfa\x8f\x0d\xcd\x8d\x14\x99\xc3\x64"
"\xea\x7f\xf3\x88\xe9\xf7\x4f\x4c\x12\xe9\x0e\x23\xad\x73\x7d"
"\xa3\x4c\x45\x3f\xb3\x48\xb7\x44\x89\x41\x20\x7b\x2c\xbd\xf2"
"\x89\x16\x1f\xbd\x80\x24\x72\xa1\x8d\x4b\x13\x74\xb2\xf4\xdf"
"\x49\xe0\x6c\x40\x0d\xf2\x7c\x8a\xbf\xf2\xb1\x62\xe0\x7e\x51"
"\x9a\xd4\x60\x64\x49\x96\x4b\x83\x91\xe5\x51\x50\x94\x3c\x41"
"\xf6\xd1\xef\x1f\x90\x5a\x48\xa5\xe2\xf8\xe3\xd9\xf9\x82\x5e"
"\xa1\x5c\x85\x1c\xbe\x47\xa2\x29\xb7\x5a\xf4\x14\x24\x92\x11"
"\x4b\x6b\x54\x95\x5e\x9f\x1b\xda\x02\xa3\x84\xb3\x2b\x07\x13"
"\x18\x6b\x31\xb4\xc1\x04\x30\x5f\xa0\xa2\xe9\xe6\x50\x6f\xed"
"\x15\x10\xf5\xda\xa1\xe5\x06\xaf\x28\xe0\x53\xea\x88\x49\xf8"
"\x97\x52\x4b\xe8\xa2\xce\x9f\xc7\x47\x4f\xd6\xc0\xe2\xb7\xc1"
"\x7f\xa9\x54\x3d\x11\xe4\x99\x28\x65\x39\xb1\xf3\xec\x48\x43"
"\x58\x19\x12\xf6\x38\x5b\xee\xca\x33\x8e\x4d",
236);
r[56] = syscall(SYS_write, r[2], 0x20057000ul, 0x9cul, 0, 0, 0);
memcpy((void*)0x2005bfa7, "\x2f\x64\x65\x76\x2f\x76\x68\x63\x69\x00",
10);
return 0;
}


The hang stack is:

[<ffffffff85309f77>] snd_seq_oss_writeq_sync+0x327/0x790
sound/core/seq/oss/seq_oss_writeq.c:121
[<ffffffff852fa353>] snd_seq_oss_drain_write+0x113/0x160
sound/core/seq/oss/seq_oss_init.c:448
[<ffffffff852f8d04>] odev_release+0x44/0x80 sound/core/seq/oss/seq_oss.c:152
[<ffffffff817ccdc6>] __fput+0x236/0x780 fs/file_table.c:208
[<ffffffff817cd395>] ____fput+0x15/0x20 fs/file_table.c:244
[<ffffffff813b8db0>] task_work_run+0x170/0x210 kernel/task_work.c:115
[< inline >] exit_task_work include/linux/task_work.h:21
[<ffffffff81363ca0>] do_exit+0xaf0/0x2d20 kernel/exit.c:748
[<ffffffff81366048>] do_group_exit+0x108/0x330 kernel/exit.c:878
[< inline >] SYSC_exit_group kernel/exit.c:889
[<ffffffff8136628d>] SyS_exit_group+0x1d/0x20 kernel/exit.c:887
[<ffffffff866a3236>] entry_SYSCALL_64_fastpath+0x16/0x7a
arch/x86/entry/entry_64.S:185


On commit fc77dbd34c5c99bce46d40a2491937c3bcbd10af (4.5-rc6).