blob: d8efcc874336b3d5abec90f296dbd8a3b0069d8a [file] [log] [blame]
// INFO: task hung in p9_fd_close
// https://syzkaller.appspot.com/bug?id=4e122f38708160e5fe03d870d6af29b45493efab
// status:open
// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <endian.h>
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <linux/futex.h>
static void sleep_ms(uint64_t ms)
{
usleep(ms * 1000);
}
static uint64_t current_time_ms(void)
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts))
exit(1);
return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
}
static void thread_start(void* (*fn)(void*), void* arg)
{
pthread_t th;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 128 << 10);
int i;
for (i = 0; i < 100; i++) {
if (pthread_create(&th, &attr, fn, arg) == 0) {
pthread_attr_destroy(&attr);
return;
}
if (errno == EAGAIN) {
usleep(50);
continue;
}
break;
}
exit(1);
}
typedef struct {
int state;
} event_t;
static void event_init(event_t* ev)
{
ev->state = 0;
}
static void event_reset(event_t* ev)
{
ev->state = 0;
}
static void event_set(event_t* ev)
{
if (ev->state)
exit(1);
__atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
syscall(SYS_futex, &ev->state, FUTEX_WAKE | FUTEX_PRIVATE_FLAG);
}
static void event_wait(event_t* ev)
{
while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, 0);
}
static int event_isset(event_t* ev)
{
return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
}
static int event_timedwait(event_t* ev, uint64_t timeout)
{
uint64_t start = current_time_ms();
uint64_t now = start;
for (;;) {
uint64_t remain = timeout - (now - start);
struct timespec ts;
ts.tv_sec = remain / 1000;
ts.tv_nsec = (remain % 1000) * 1000 * 1000;
syscall(SYS_futex, &ev->state, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 0, &ts);
if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED))
return 1;
now = current_time_ms();
if (now - start > timeout)
return 0;
}
}
struct thread_t {
int created, call;
event_t ready, done;
};
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 (;;) {
event_wait(&th->ready);
event_reset(&th->ready);
execute_call(th->call);
__atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
event_set(&th->done);
}
return 0;
}
static void loop(void)
{
int i, call, thread;
int collide = 0;
again:
for (call = 0; call < 5; call++) {
for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
thread++) {
struct thread_t* th = &threads[thread];
if (!th->created) {
th->created = 1;
event_init(&th->ready);
event_init(&th->done);
event_set(&th->done);
thread_start(thr, th);
}
if (!event_isset(&th->done))
continue;
event_reset(&th->done);
th->call = call;
__atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
event_set(&th->ready);
if (collide && (call % 2) == 0)
break;
event_timedwait(&th->done, 45);
break;
}
}
for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
sleep_ms(1);
if (!collide) {
collide = 1;
goto again;
}
}
uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
void execute_call(int call)
{
intptr_t res;
switch (call) {
case 0:
res = syscall(__NR_eventfd2, 0, 0);
if (res != -1)
r[0] = res;
break;
case 1:
res = syscall(__NR_dup, r[0]);
if (res != -1)
r[1] = res;
break;
case 2:
memcpy(
(void*)0x20000700,
"\x20\x00\x70\x70\x70\x30\x3a\xf5\x32\x6d\x65\x5f\x74\x79\x70\x65\x77"
"\x6c\x61\x6e\x30\x47\x50\x39\xd6\x72\xce\x69\x2d\x2e\x12\x79\x70\x6f"
"\x73\x69\x78\x5f\x61\x63\x6c\x5f\x61\x63\x63\x65\x73\x73\x25\x6d\x64"
"\x35\x73\x35\x6d\x70\x72\x6f\x63\x65\x6d\x30\x2d\x7b\x2c\x76\x2a\x70"
"\x70\x70\x31\x6e\x65\x74\x31\x2b\x40\x77\x6c\x61\x6e\x31\x65\x74\x68"
"\x31\x00\x65\x14\x90\x8f\xf4\xd9\x9d\x1d\xd1\xf1\x3a\x33\x36\xab\x62"
"\xd9\x3f\xb6\xf1\x99\x93\xdb\x0d\x95\xb2\x78\x97\x06\x88\xd4\x76\x09"
"\x9b\xb0\xc4\x94\x60\x99\x2d\xe3\x55\x9b\x77\x31\x62\x78\xf1\x79\xb3"
"\x46\x7f\x4a\x23\xc1\x9e\xb2\x79\x07\x2b\xa4\x08\x00\x3f\xa9\xf3\x9a"
"\xab\x46\x99\xd2\x20\x85\xec\x0d\x1a\xd5\xc3\xa7\x30\x5d\xb8\xe9\x87"
"\x94\x98\x0c\x3a\x4b\xf2\x6c\x23\x63\xcb\xf4\xe7\xec\x56\xca\x06\xd1"
"\x21\x22\x59\xf1\xd5\xa1\x75\xed\xf0\xc9\x1d\x18\x7a\x6f\x24\x7f\xb0"
"\x5a\x61\x5e\x64\x79\x67\x75\x01\xf6\x97\x52\x23\x4e\xd7\xdb\xdf\xef"
"\x2b\x9a\x0f\x57\x79\x45\xf4\x5c\x34\x73\x64\x54\x5a\x7f\x19\x07\x41"
"\x92\xa3\x62\x73\x47\x35\x9a\x21\x87\x5b\x88\x95\x2d\x6f\xeb\xf4\x09"
"\xbc\x03\x51\x25\x92\xb2\xc6\x13\x10\x44\x23\xa5\x0e\x90\xf6\xad\x69"
"\x36\x88\x73\x69\xb0\x3e\x71\xb1\x45\x89\xd6\xdc\x51\x33\x21\x24\x8c"
"\x4b\x72\x82\xc5\xc2\x6c\x9c\xeb\x3b\x3f\x7e\x55\xda\xec\x61\x5f\xca"
"\xf4\x20\x8d\x26\x53\xf5\x8d\x30\xf1\x56\x8f\x7b\x57\xf5\xf2\x50\x45"
"\xc1\xdd\x4e\x8d\x1f\xd4\xdf\x16\xd4\x13\x99\x91\xfe\xeb\x01\xc2\x4c"
"\xa3\x17\xb7\x74\x2a\xdd\xd8\xe0\x8d\xc4\xa6\x52\x84\xdd\x7c\x1b\x71"
"\xfc\xc2\xd2\xed\x99\x5a\x00\xd2\xa6\x95\x1d\xe3\x00\xc8\xf0\x36\x89"
"\x81\x5c\x60\x34\xc3\xf2\x5c\x4b\x75\xe7\x18\x53\x00\xb4\x10\xae\x36"
"\xdf\x53\xea\x08\x70\x4f\x4e\x99\x1e\x2a\x13\x69\x32\xe3\x1d\x82\x86"
"\x44\xfc\x6f\xf6\xb8\xc5\xf4\xe7\x33\x50\xff\x6f\xe2\x76\xeb\xd0\xc7"
"\x72\xe1\xfd\x50\x33\x1a\x39\x96\xbb\x81\x08\x86\x3d\x17\x9d\xbb\x30"
"\x1e\xb9\x3b\x74\xc3\xdb\x4e\x9e\xaf\xd1\xe3\x2e\x33\xe3\xc1\xc4\x10"
"\x58\xe9\x9b\x98\x22\x4a\x65\x31\x66\xf3\xdd\x2d\xdc\x31\xf1\xd5\x57"
"\x4d\x1d\x8a\xcb\x47\x9d\xe3\x06\x2b\x85\x62\xe5\xcf\x47\xef\xf3\xc9"
"\xf4\xe9\xfa\x9a\x28\x00\x25\x17\x2a\xc9\x38\xb2\x01\xf4\x41\x12\x56"
"\x08\x9f\x72\xe0\x68\x66\x4b\xba\xc1\x25\x18\xc3\x0a\x19\xc9\x21\xbd"
"\xd3\x79\x1e\x98\x61\xdf\x74\x90\xb2\x9b\xa7\x33\x68\x7f\x32\x1f\x5d"
"\xb3\x64\xe2\x7e\x55\x1a\x14\xac\x80\x79\xe4\x2e\x9e\x14\x91\x9c\x20"
"\xb1\x47\xe0\xc5\xf1\x50\x41\x79\x29\x1b\x19\xe1\xef\xe9\x28\x62\x12"
"\x5b\x2b\x09\x7c\xe9\x46\x44\x3e\x21\xe7\x82\xbb\x24\xde\xfe\x01\x9d"
"\x7f\x55\x19\x67\x46\x7d\x14\xb4\xde\x12\x40\xc4\x34\xe4\x82\xb6\xeb"
"\xb5\x29\xed\x10\x5a\x69\x0a\x94\xb6\x36\x05\xae\x93\x81\x3c\xf8\x33"
"\x3b\x2e\xec\xcd\xcc\x68\xa9\x26\x4f\xd7\x63\x26\xb8\x42\x3d\xf7\x2a"
"\x71\xbd\x24\x53\xb9\x42\xae\xb7\xc1\xdc\x53\x65\xb5\x80\x82\x2e\x11"
"\xd0\xf3\x87\xe0\xa1\x3c\x1d\xae\x95\xe5\x48\x9f\xa4\x7c\x47\x3f\x42"
"\xfc\x17\x75\x6b\x89\xa0\xa2\xe1\xc3\xe7\x41\x99\xdc\x03\x5a\x39\xb5"
"\x81\xf0\xf0\xb7\x2e\x06\x5f\xe4\x0a\xde\xcd\x54\xcb\xe5\xc0\xa7\x44"
"\x58\x34\x9b\x0b\x87\xa0\x40\x7a\x89\xe0\x4d\x59\xbb\x5f\x8f\x0b\x1c"
"\x21\x47\xd8\x4a\xde\x0b\xca\xec\xcb\x69\x7c\x69\x92\xc0\x12\x31\xfb"
"\x35\x1c\xac\x21\x83\xa7\xb0\x75\x8c\x48\xb9\x66\x46\xae\x38\xb3\x9a"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\xe0"
"\x1b\x4e\x05\xda\x65\xf3\x0f\xf4\x0c\x4d\xb0\x4c\xec\x86\x2a\x54\xb4"
"\xce\x27\x0e\x70\xd9\x37\x5b\x73\xb6\x93\x0a\x9d\x32\xa1\xef\x7c\x46"
"\x77\x52\x80\x21\x26\xbd\x90\xed\x92\x22\x63\xda\x4c\x48\x19\xa5\xd5"
"\x47\x14\xe1\xe8\x75\xd5\x8b\xb0\x04\xbf\x1f\x27\x1d\xc9\x23\xb7\x4a"
"\x39\xb2\xde\x17\x0b\xf2\xd6\x8d\x30\x70\xcc\x11\x98\xf1\x44\x20\x81"
"\x2d\x38\xea\x05\xa3\x28\xc8\x0c\xd0\x27\x3a\x1f\x60\x15\xfb\x9a\x27"
"\x9d\x85\x52\xb7\x88\x60\x67\xdc\x19\x70\x97\xb7\x5b\x83\x00\x71\x1b"
"\x40\x5e\x20\xf9\x1d\x73\x85\x08\x9d\x71\x30\x65\x5d\x31\x41\xf1\xa4"
"\xc2\x7e\xd3\x63\x47\x6c\xa7\xbc\x65\x16\x85\x3d\x42\x58\xb1\x3f\x5d"
"\x4c\xf6\xc8\x48\xfc\xa7\x3e\xfa\x4c\x29\xaa\xfd\xfe\xfe\x3e\x85\x78"
"\x57\x02\x7f\xbc\x26\x54\x53\xec\x57\x82\xc3\x1c\xd6\x3c\xd5\xe1\x94"
"\xc5\x1a\x09\xe1\x10\x17\xe8\x69\x3e\x04\xe2\x26\x7e\xe2\x52\x27\x71"
"\xb2\xa1\x2e\xb8\xac\xa2\x5e\x02\x0c\x4a\x57\x8e\x8b\x44\x44\xbd\xa4"
"\xba\x96\xfa\x02\x30\xf5\xa7\x92\xca\x05",
1013);
syscall(__NR_write, r[1], 0x20000700, 0xe4);
break;
case 3:
memcpy((void*)0x20000000, "./file1\000", 8);
memcpy((void*)0x20000040, "9p\000", 3);
memcpy((void*)0x20000140, "trans=fd,", 9);
memcpy((void*)0x20000149, "rfdno", 5);
*(uint8_t*)0x2000014e = 0x3d;
sprintf((char*)0x2000014f, "0x%016llx", (long long)r[1]);
*(uint8_t*)0x20000161 = 0x2c;
memcpy((void*)0x20000162, "wfdno", 5);
*(uint8_t*)0x20000167 = 0x3d;
sprintf((char*)0x20000168, "0x%016llx", (long long)r[1]);
*(uint8_t*)0x2000017a = 0x2c;
memcpy((void*)0x2000017b, "aname", 5);
*(uint8_t*)0x20000180 = 0x3d;
memcpy((void*)0x20000181, "vmnet0self", 10);
*(uint8_t*)0x2000018b = 0x2c;
memcpy((void*)0x2000018c, "loose", 5);
*(uint8_t*)0x20000191 = 0x2c;
memcpy((void*)0x20000192, "fowner<", 7);
sprintf((char*)0x20000199, "%020llu", (long long)0);
*(uint8_t*)0x200001ad = 0x2c;
memcpy((void*)0x200001ae, "permit_directio", 15);
*(uint8_t*)0x200001bd = 0x2c;
memcpy((void*)0x200001be, "fsname", 6);
*(uint8_t*)0x200001c4 = 0x3d;
memcpy((void*)0x200001c5, "(.\\nodev", 8);
*(uint8_t*)0x200001cd = 0x2c;
memcpy((void*)0x200001ce, "uid<", 4);
sprintf((char*)0x200001d2, "%020llu", (long long)0);
*(uint8_t*)0x200001e6 = 0x2c;
*(uint8_t*)0x200001e7 = 0;
syscall(__NR_mount, 0, 0x20000000, 0x20000040, 1, 0x20000140);
break;
case 4:
memcpy((void*)0x200000c0, "./file1\000", 8);
syscall(__NR_open, 0x200000c0, 0x220141042, 0);
break;
}
}
int main(void)
{
syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0);
loop();
return 0;
}