blob: 0c7c0dee4c6def103d505c6f40a970524d717bc0 [file] [log] [blame]
// KASAN: null-ptr-deref Read in snd_timer_user_read
// https://syzkaller.appspot.com/bug?id=ab2b76b5454b77fb2249e858b8c74c1f7d552ab5
// status:open
// autogenerated by syzkaller (http://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <fcntl.h>
#include <linux/futex.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
static uintptr_t syz_open_dev(uintptr_t a0, uintptr_t a1, uintptr_t a2)
{
if (a0 == 0xc || a0 == 0xb) {
char buf[128];
sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1,
(uint8_t)a2);
return open(buf, O_RDWR, 0);
} else {
char buf[1024];
char* hash;
strncpy(buf, (char*)a0, sizeof(buf));
buf[sizeof(buf) - 1] = 0;
while ((hash = strchr(buf, '#'))) {
*hash = '0' + (char)(a1 % 10);
a1 /= 10;
}
return open(buf, a2, 0);
}
}
struct thread_t {
int created, running, call;
pthread_t th;
};
static struct thread_t threads[16];
static void execute_call(int call);
static int running;
static void* thr(void* arg)
{
struct thread_t* th = (struct thread_t*)arg;
for (;;) {
while (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE))
syscall(SYS_futex, &th->running, FUTEX_WAIT, 0, 0);
execute_call(th->call);
__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
__atomic_store_n(&th->running, 0, __ATOMIC_RELEASE);
syscall(SYS_futex, &th->running, FUTEX_WAKE);
}
return 0;
}
static void execute(int num_calls)
{
int call, thread;
running = 0;
for (call = 0; call < num_calls; call++) {
for (thread = 0; thread < sizeof(threads) / sizeof(threads[0]); thread++) {
struct thread_t* th = &threads[thread];
if (!th->created) {
th->created = 1;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 128 << 10);
pthread_create(&th->th, &attr, thr, th);
}
if (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) {
th->call = call;
__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
__atomic_store_n(&th->running, 1, __ATOMIC_RELEASE);
syscall(SYS_futex, &th->running, FUTEX_WAKE);
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 20 * 1000 * 1000;
syscall(SYS_futex, &th->running, FUTEX_WAIT, 1, &ts);
if (running)
usleep((call == num_calls - 1) ? 10000 : 1000);
break;
}
}
}
}
long r[1];
void execute_call(int call)
{
switch (call) {
case 0:
syscall(__NR_mmap, 0x20000000, 0xfff000, 3, 0x32, -1, 0);
break;
case 1:
memcpy((void*)0x20061000, "/dev/snd/timer", 15);
r[0] = syz_open_dev(0x20061000, 0, 0);
break;
case 2:
*(uint32_t*)0x2060c000 = 1;
*(uint32_t*)0x2060c004 = 0;
*(uint32_t*)0x2060c008 = 0;
*(uint32_t*)0x2060c00c = 0;
*(uint32_t*)0x2060c010 = 0;
*(uint8_t*)0x2060c014 = 0;
*(uint8_t*)0x2060c015 = 0;
*(uint8_t*)0x2060c016 = 0;
*(uint8_t*)0x2060c017 = 0;
*(uint8_t*)0x2060c018 = 0;
*(uint8_t*)0x2060c019 = 0;
*(uint8_t*)0x2060c01a = 0;
*(uint8_t*)0x2060c01b = 0;
*(uint8_t*)0x2060c01c = 0;
*(uint8_t*)0x2060c01d = 0;
*(uint8_t*)0x2060c01e = 0;
*(uint8_t*)0x2060c01f = 0;
*(uint8_t*)0x2060c020 = 0;
*(uint8_t*)0x2060c021 = 0;
*(uint8_t*)0x2060c022 = 0;
*(uint8_t*)0x2060c023 = 0;
*(uint8_t*)0x2060c024 = 0;
*(uint8_t*)0x2060c025 = 0;
*(uint8_t*)0x2060c026 = 0;
*(uint8_t*)0x2060c027 = 0;
*(uint8_t*)0x2060c028 = 0;
*(uint8_t*)0x2060c029 = 0;
*(uint8_t*)0x2060c02a = 0;
*(uint8_t*)0x2060c02b = 0;
*(uint8_t*)0x2060c02c = 0;
*(uint8_t*)0x2060c02d = 0;
*(uint8_t*)0x2060c02e = 0;
*(uint8_t*)0x2060c02f = 0;
*(uint8_t*)0x2060c030 = 0;
*(uint8_t*)0x2060c031 = 0;
*(uint8_t*)0x2060c032 = 0;
*(uint8_t*)0x2060c033 = 0;
syscall(__NR_ioctl, r[0], 0x40345410, 0x2060c000);
break;
case 3:
syscall(__NR_ioctl, r[0], 0x54a0);
break;
case 4:
*(uint32_t*)0x204da000 = r[0];
*(uint16_t*)0x204da004 = 0;
*(uint16_t*)0x204da006 = 0;
*(uint32_t*)0x204da008 = -1;
*(uint16_t*)0x204da00c = 0x2040;
*(uint16_t*)0x204da00e = 0;
syscall(__NR_poll, 0x204da000, 2, 0xffffff80);
break;
case 5:
*(uint32_t*)0x201e1fcc = 2;
*(uint32_t*)0x201e1fd0 = 0;
*(uint32_t*)0x201e1fd4 = 0x257;
*(uint32_t*)0x201e1fd8 = 3;
*(uint32_t*)0x201e1fdc = 5;
*(uint8_t*)0x201e1fe0 = 0;
*(uint8_t*)0x201e1fe1 = 0;
*(uint8_t*)0x201e1fe2 = 0;
*(uint8_t*)0x201e1fe3 = 0;
*(uint8_t*)0x201e1fe4 = 0;
*(uint8_t*)0x201e1fe5 = 0;
*(uint8_t*)0x201e1fe6 = 0;
*(uint8_t*)0x201e1fe7 = 0;
*(uint8_t*)0x201e1fe8 = 0;
*(uint8_t*)0x201e1fe9 = 0;
*(uint8_t*)0x201e1fea = 0;
*(uint8_t*)0x201e1feb = 0;
*(uint8_t*)0x201e1fec = 0;
*(uint8_t*)0x201e1fed = 0;
*(uint8_t*)0x201e1fee = 0;
*(uint8_t*)0x201e1fef = 0;
*(uint8_t*)0x201e1ff0 = 0;
*(uint8_t*)0x201e1ff1 = 0;
*(uint8_t*)0x201e1ff2 = 0;
*(uint8_t*)0x201e1ff3 = 0;
*(uint8_t*)0x201e1ff4 = 0;
*(uint8_t*)0x201e1ff5 = 0;
*(uint8_t*)0x201e1ff6 = 0;
*(uint8_t*)0x201e1ff7 = 0;
*(uint8_t*)0x201e1ff8 = 0;
*(uint8_t*)0x201e1ff9 = 0;
*(uint8_t*)0x201e1ffa = 0;
*(uint8_t*)0x201e1ffb = 0;
*(uint8_t*)0x201e1ffc = 0;
*(uint8_t*)0x201e1ffd = 0;
*(uint8_t*)0x201e1ffe = 0;
*(uint8_t*)0x201e1fff = 0;
syscall(__NR_ioctl, r[0], 0x40345410, 0x201e1fcc);
break;
case 6:
*(uint32_t*)0x20c2bffc = 1;
syscall(__NR_ioctl, r[0], 0x40045402, 0x20c2bffc);
break;
case 7:
*(uint64_t*)0x20690fa0 = 0x204e0000;
*(uint64_t*)0x20690fa8 = 0x4c;
*(uint64_t*)0x20690fb0 = 0x20546000;
*(uint64_t*)0x20690fb8 = 0x1000;
*(uint64_t*)0x20690fc0 = 0x206c5000;
*(uint64_t*)0x20690fc8 = 3;
*(uint64_t*)0x20690fd0 = 0x20fc3000;
*(uint64_t*)0x20690fd8 = 0xe2;
*(uint64_t*)0x20690fe0 = 0x20883000;
*(uint64_t*)0x20690fe8 = 0xa7;
*(uint64_t*)0x20690ff0 = 0x20ef2000;
*(uint64_t*)0x20690ff8 = 0x1000;
syscall(__NR_readv, r[0], 0x20690fa0, 6);
break;
}
}
void loop()
{
memset(r, -1, sizeof(r));
execute(8);
}
int main()
{
loop();
return 0;
}