xref: /freebsd/tools/test/stress2/misc/syzkaller58.sh (revision 7f658f99)
12d4b1f4bSPeter Holm#!/bin/sh
22d4b1f4bSPeter Holm
32d4b1f4bSPeter Holm# panic: td 0xfffffe010e6ff000 is not suspended
42d4b1f4bSPeter Holm# cpuid = 2
52d4b1f4bSPeter Holm# time = 1654661460
62d4b1f4bSPeter Holm# KDB: stack backtrace:
72d4b1f4bSPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0143924c10
82d4b1f4bSPeter Holm# vpanic() at vpanic+0x17f/frame 0xfffffe0143924c60
92d4b1f4bSPeter Holm# panic() at panic+0x43/frame 0xfffffe0143924cc0
102d4b1f4bSPeter Holm# thread_single() at thread_single+0x736/frame 0xfffffe0143924d40
112d4b1f4bSPeter Holm# fork1() at fork1+0x1e1/frame 0xfffffe0143924da0
122d4b1f4bSPeter Holm# sys_rfork() at sys_rfork+0xa4/frame 0xfffffe0143924e00
132d4b1f4bSPeter Holm# amd64_syscall() at amd64_syscall+0x145/frame 0xfffffe0143924f30
142d4b1f4bSPeter Holm# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0143924f30
152d4b1f4bSPeter Holm# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x821be4d1a, rsp = 0x8276b8f48, rbp = 0x8276b8f70 ---
162d4b1f4bSPeter Holm# KDB: enter: panic
172d4b1f4bSPeter Holm# [ thread pid 2860 tid 100362 ]
182d4b1f4bSPeter Holm# Stopped at      kdb_enter+0x32: movq    $0,0x1277d83(%rip)
192d4b1f4bSPeter Holm# db> x/s version
202d4b1f4bSPeter Holm# FreeBSD 14.0-CURRENT #0 reap-n255837-0bdda1ded8d: Thu May 26 22:38:04 CEST 2022
212d4b1f4bSPeter Holm# pho@mercat1.netperf.freebsd.org:/var/tmp/deviant3/sys/amd64/compile/PHO
222d4b1f4bSPeter Holm# db>
232d4b1f4bSPeter Holm
242d4b1f4bSPeter Holm# Submitted by:	 markj
252d4b1f4bSPeter Holm
262d4b1f4bSPeter Holm[ `uname -p` != "amd64" ] && exit 0
272d4b1f4bSPeter Holm
282d4b1f4bSPeter Holm. ../default.cfg
292d4b1f4bSPeter Holmcat > /tmp/syzkaller58.c <<EOF
302d4b1f4bSPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller)
312d4b1f4bSPeter Holm
322d4b1f4bSPeter Holm#define _GNU_SOURCE
332d4b1f4bSPeter Holm
342d4b1f4bSPeter Holm#include <sys/types.h>
352d4b1f4bSPeter Holm
362d4b1f4bSPeter Holm#include <errno.h>
372d4b1f4bSPeter Holm#include <pthread.h>
382d4b1f4bSPeter Holm#include <pwd.h>
392d4b1f4bSPeter Holm#include <signal.h>
402d4b1f4bSPeter Holm#include <stdarg.h>
412d4b1f4bSPeter Holm#include <stdbool.h>
422d4b1f4bSPeter Holm#include <stdint.h>
432d4b1f4bSPeter Holm#include <stdio.h>
442d4b1f4bSPeter Holm#include <stdlib.h>
452d4b1f4bSPeter Holm#include <string.h>
462d4b1f4bSPeter Holm#include <sys/endian.h>
472d4b1f4bSPeter Holm#include <sys/syscall.h>
482d4b1f4bSPeter Holm#include <sys/wait.h>
492d4b1f4bSPeter Holm#include <time.h>
502d4b1f4bSPeter Holm#include <unistd.h>
512d4b1f4bSPeter Holm
522d4b1f4bSPeter Holmstatic unsigned long long procid;
532d4b1f4bSPeter Holm
542d4b1f4bSPeter Holmstatic void kill_and_wait(int pid, int* status)
552d4b1f4bSPeter Holm{
562d4b1f4bSPeter Holm  kill(pid, SIGKILL);
572d4b1f4bSPeter Holm  while (waitpid(-1, status, 0) != pid) {
582d4b1f4bSPeter Holm  }
592d4b1f4bSPeter Holm}
602d4b1f4bSPeter Holm
612d4b1f4bSPeter Holmstatic void sleep_ms(uint64_t ms)
622d4b1f4bSPeter Holm{
632d4b1f4bSPeter Holm  usleep(ms * 1000);
642d4b1f4bSPeter Holm}
652d4b1f4bSPeter Holm
662d4b1f4bSPeter Holmstatic uint64_t current_time_ms(void)
672d4b1f4bSPeter Holm{
682d4b1f4bSPeter Holm  struct timespec ts;
692d4b1f4bSPeter Holm  if (clock_gettime(CLOCK_MONOTONIC, &ts))
702d4b1f4bSPeter Holm    exit(1);
712d4b1f4bSPeter Holm  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
722d4b1f4bSPeter Holm}
732d4b1f4bSPeter Holm
742d4b1f4bSPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg)
752d4b1f4bSPeter Holm{
762d4b1f4bSPeter Holm  pthread_t th;
772d4b1f4bSPeter Holm  pthread_attr_t attr;
782d4b1f4bSPeter Holm  pthread_attr_init(&attr);
792d4b1f4bSPeter Holm  pthread_attr_setstacksize(&attr, 128 << 10);
802d4b1f4bSPeter Holm  int i = 0;
812d4b1f4bSPeter Holm  for (; i < 100; i++) {
822d4b1f4bSPeter Holm    if (pthread_create(&th, &attr, fn, arg) == 0) {
832d4b1f4bSPeter Holm      pthread_attr_destroy(&attr);
842d4b1f4bSPeter Holm      return;
852d4b1f4bSPeter Holm    }
862d4b1f4bSPeter Holm    if (errno == EAGAIN) {
872d4b1f4bSPeter Holm      usleep(50);
882d4b1f4bSPeter Holm      continue;
892d4b1f4bSPeter Holm    }
902d4b1f4bSPeter Holm    break;
912d4b1f4bSPeter Holm  }
922d4b1f4bSPeter Holm  exit(1);
932d4b1f4bSPeter Holm}
942d4b1f4bSPeter Holm
952d4b1f4bSPeter Holmtypedef struct {
962d4b1f4bSPeter Holm  pthread_mutex_t mu;
972d4b1f4bSPeter Holm  pthread_cond_t cv;
982d4b1f4bSPeter Holm  int state;
992d4b1f4bSPeter Holm} event_t;
1002d4b1f4bSPeter Holm
1012d4b1f4bSPeter Holmstatic void event_init(event_t* ev)
1022d4b1f4bSPeter Holm{
1032d4b1f4bSPeter Holm  if (pthread_mutex_init(&ev->mu, 0))
1042d4b1f4bSPeter Holm    exit(1);
1052d4b1f4bSPeter Holm  if (pthread_cond_init(&ev->cv, 0))
1062d4b1f4bSPeter Holm    exit(1);
1072d4b1f4bSPeter Holm  ev->state = 0;
1082d4b1f4bSPeter Holm}
1092d4b1f4bSPeter Holm
1102d4b1f4bSPeter Holmstatic void event_reset(event_t* ev)
1112d4b1f4bSPeter Holm{
1122d4b1f4bSPeter Holm  ev->state = 0;
1132d4b1f4bSPeter Holm}
1142d4b1f4bSPeter Holm
1152d4b1f4bSPeter Holmstatic void event_set(event_t* ev)
1162d4b1f4bSPeter Holm{
1172d4b1f4bSPeter Holm  pthread_mutex_lock(&ev->mu);
1182d4b1f4bSPeter Holm  if (ev->state)
1192d4b1f4bSPeter Holm    exit(1);
1202d4b1f4bSPeter Holm  ev->state = 1;
1212d4b1f4bSPeter Holm  pthread_mutex_unlock(&ev->mu);
1222d4b1f4bSPeter Holm  pthread_cond_broadcast(&ev->cv);
1232d4b1f4bSPeter Holm}
1242d4b1f4bSPeter Holm
1252d4b1f4bSPeter Holmstatic void event_wait(event_t* ev)
1262d4b1f4bSPeter Holm{
1272d4b1f4bSPeter Holm  pthread_mutex_lock(&ev->mu);
1282d4b1f4bSPeter Holm  while (!ev->state)
1292d4b1f4bSPeter Holm    pthread_cond_wait(&ev->cv, &ev->mu);
1302d4b1f4bSPeter Holm  pthread_mutex_unlock(&ev->mu);
1312d4b1f4bSPeter Holm}
1322d4b1f4bSPeter Holm
1332d4b1f4bSPeter Holmstatic int event_isset(event_t* ev)
1342d4b1f4bSPeter Holm{
1352d4b1f4bSPeter Holm  pthread_mutex_lock(&ev->mu);
1362d4b1f4bSPeter Holm  int res = ev->state;
1372d4b1f4bSPeter Holm  pthread_mutex_unlock(&ev->mu);
1382d4b1f4bSPeter Holm  return res;
1392d4b1f4bSPeter Holm}
1402d4b1f4bSPeter Holm
1412d4b1f4bSPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout)
1422d4b1f4bSPeter Holm{
1432d4b1f4bSPeter Holm  uint64_t start = current_time_ms();
1442d4b1f4bSPeter Holm  uint64_t now = start;
1452d4b1f4bSPeter Holm  pthread_mutex_lock(&ev->mu);
1462d4b1f4bSPeter Holm  for (;;) {
1472d4b1f4bSPeter Holm    if (ev->state)
1482d4b1f4bSPeter Holm      break;
1492d4b1f4bSPeter Holm    uint64_t remain = timeout - (now - start);
1502d4b1f4bSPeter Holm    struct timespec ts;
1512d4b1f4bSPeter Holm    ts.tv_sec = remain / 1000;
1522d4b1f4bSPeter Holm    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
1532d4b1f4bSPeter Holm    pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
1542d4b1f4bSPeter Holm    now = current_time_ms();
1552d4b1f4bSPeter Holm    if (now - start > timeout)
1562d4b1f4bSPeter Holm      break;
1572d4b1f4bSPeter Holm  }
1582d4b1f4bSPeter Holm  int res = ev->state;
1592d4b1f4bSPeter Holm  pthread_mutex_unlock(&ev->mu);
1602d4b1f4bSPeter Holm  return res;
1612d4b1f4bSPeter Holm}
1622d4b1f4bSPeter Holm
1632d4b1f4bSPeter Holmstruct thread_t {
1642d4b1f4bSPeter Holm  int created, call;
1652d4b1f4bSPeter Holm  event_t ready, done;
1662d4b1f4bSPeter Holm};
1672d4b1f4bSPeter Holm
1682d4b1f4bSPeter Holmstatic struct thread_t threads[16];
1692d4b1f4bSPeter Holmstatic void execute_call(int call);
1702d4b1f4bSPeter Holmstatic int running;
1712d4b1f4bSPeter Holm
1722d4b1f4bSPeter Holmstatic void* thr(void* arg)
1732d4b1f4bSPeter Holm{
1742d4b1f4bSPeter Holm  struct thread_t* th = (struct thread_t*)arg;
1752d4b1f4bSPeter Holm  for (;;) {
1762d4b1f4bSPeter Holm    event_wait(&th->ready);
1772d4b1f4bSPeter Holm    event_reset(&th->ready);
1782d4b1f4bSPeter Holm    execute_call(th->call);
1792d4b1f4bSPeter Holm    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
1802d4b1f4bSPeter Holm    event_set(&th->done);
1812d4b1f4bSPeter Holm  }
1822d4b1f4bSPeter Holm  return 0;
1832d4b1f4bSPeter Holm}
1842d4b1f4bSPeter Holm
1852d4b1f4bSPeter Holmstatic void execute_one(void)
1862d4b1f4bSPeter Holm{
1872d4b1f4bSPeter Holm  int i, call, thread;
1882d4b1f4bSPeter Holm  for (call = 0; call < 5; call++) {
1892d4b1f4bSPeter Holm    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
1902d4b1f4bSPeter Holm         thread++) {
1912d4b1f4bSPeter Holm      struct thread_t* th = &threads[thread];
1922d4b1f4bSPeter Holm      if (!th->created) {
1932d4b1f4bSPeter Holm        th->created = 1;
1942d4b1f4bSPeter Holm        event_init(&th->ready);
1952d4b1f4bSPeter Holm        event_init(&th->done);
1962d4b1f4bSPeter Holm        event_set(&th->done);
1972d4b1f4bSPeter Holm        thread_start(thr, th);
1982d4b1f4bSPeter Holm      }
1992d4b1f4bSPeter Holm      if (!event_isset(&th->done))
2002d4b1f4bSPeter Holm        continue;
2012d4b1f4bSPeter Holm      event_reset(&th->done);
2022d4b1f4bSPeter Holm      th->call = call;
2032d4b1f4bSPeter Holm      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
2042d4b1f4bSPeter Holm      event_set(&th->ready);
2052d4b1f4bSPeter Holm      event_timedwait(&th->done, 50);
2062d4b1f4bSPeter Holm      break;
2072d4b1f4bSPeter Holm    }
2082d4b1f4bSPeter Holm  }
2092d4b1f4bSPeter Holm  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
2102d4b1f4bSPeter Holm    sleep_ms(1);
2112d4b1f4bSPeter Holm}
2122d4b1f4bSPeter Holm
2132d4b1f4bSPeter Holmstatic void execute_one(void);
2142d4b1f4bSPeter Holm
2152d4b1f4bSPeter Holm#define WAIT_FLAGS 0
2162d4b1f4bSPeter Holm
2172d4b1f4bSPeter Holmstatic void loop(void)
2182d4b1f4bSPeter Holm{
2197f658f99SPeter Holm  int iter __unused = 0;
2202d4b1f4bSPeter Holm  for (;; iter++) {
2212d4b1f4bSPeter Holm    int pid = fork();
2222d4b1f4bSPeter Holm    if (pid < 0)
2232d4b1f4bSPeter Holm      exit(1);
2242d4b1f4bSPeter Holm    if (pid == 0) {
2252d4b1f4bSPeter Holm      execute_one();
2262d4b1f4bSPeter Holm      exit(0);
2272d4b1f4bSPeter Holm    }
2282d4b1f4bSPeter Holm    int status = 0;
2292d4b1f4bSPeter Holm    uint64_t start = current_time_ms();
2302d4b1f4bSPeter Holm    for (;;) {
2312d4b1f4bSPeter Holm      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
2322d4b1f4bSPeter Holm        break;
2332d4b1f4bSPeter Holm      sleep_ms(1);
2342d4b1f4bSPeter Holm      if (current_time_ms() - start < 5000)
2352d4b1f4bSPeter Holm        continue;
2362d4b1f4bSPeter Holm      kill_and_wait(pid, &status);
2372d4b1f4bSPeter Holm      break;
2382d4b1f4bSPeter Holm    }
2392d4b1f4bSPeter Holm  }
2402d4b1f4bSPeter Holm}
2412d4b1f4bSPeter Holm
2422d4b1f4bSPeter Holmvoid execute_call(int call)
2432d4b1f4bSPeter Holm{
2442d4b1f4bSPeter Holm  switch (call) {
2452d4b1f4bSPeter Holm  case 0:
2462d4b1f4bSPeter Holm    syscall(SYS_rfork, 0x93000ul);
2472d4b1f4bSPeter Holm    break;
2482d4b1f4bSPeter Holm  case 1:
2492d4b1f4bSPeter Holm    syscall(SYS_kqueue);
2502d4b1f4bSPeter Holm    break;
2512d4b1f4bSPeter Holm  case 2:
2522d4b1f4bSPeter Holm    *(uint32_t*)0x20000000 = 0x1d;
2532d4b1f4bSPeter Holm    *(uint32_t*)0x20000004 = 0;
2542d4b1f4bSPeter Holm    *(uint32_t*)0x20000008 = 0;
2552d4b1f4bSPeter Holm    *(uint32_t*)0x2000000c = 0;
2562d4b1f4bSPeter Holm    *(uint32_t*)0x20000010 = 0;
2572d4b1f4bSPeter Holm    memset((void*)0x20000014, 0, 60);
2582d4b1f4bSPeter Holm    syscall(SYS_procctl, 0ul, 0, 6ul, 0x20000000ul);
2592d4b1f4bSPeter Holm    break;
2602d4b1f4bSPeter Holm  case 3:
2612d4b1f4bSPeter Holm    syscall(SYS_kevent, -1, 0ul, 0ul, 0ul, 0ul, 0ul);
2622d4b1f4bSPeter Holm    break;
2632d4b1f4bSPeter Holm  case 4:
2642d4b1f4bSPeter Holm    syscall(SYS_truncate, 0ul, 4ul);
2652d4b1f4bSPeter Holm    break;
2662d4b1f4bSPeter Holm  }
2672d4b1f4bSPeter Holm}
2682d4b1f4bSPeter Holmint main(void)
2692d4b1f4bSPeter Holm{
2702d4b1f4bSPeter Holm  syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
2712d4b1f4bSPeter Holm  for (procid = 0; procid < 2; procid++) {
2722d4b1f4bSPeter Holm    if (fork() == 0) {
2732d4b1f4bSPeter Holm      loop();
2742d4b1f4bSPeter Holm    }
2752d4b1f4bSPeter Holm  }
2762d4b1f4bSPeter Holm  sleep(1000000);
2772d4b1f4bSPeter Holm  return 0;
2782d4b1f4bSPeter Holm}
2792d4b1f4bSPeter Holm
2802d4b1f4bSPeter Holm
2812d4b1f4bSPeter HolmEOF
2822d4b1f4bSPeter Holmmycc -o /tmp/syzkaller58 -Wall -Wextra -O0 /tmp/syzkaller58.c -lpthread \
2832d4b1f4bSPeter Holm    || exit 1
2842d4b1f4bSPeter Holm
2852d4b1f4bSPeter Holm(cd /tmp; timeout 3m ./syzkaller58)
2862d4b1f4bSPeter Holm
2872d4b1f4bSPeter Holmrm -rf /tmp/syzkaller58 /tmp/syzkaller58.c /tmp/syzkaller58.core \
2882d4b1f4bSPeter Holm    /tmp/syzkaller.??????
2892d4b1f4bSPeter Holm[ $loaded ] && kldunload sctp.ko
2902d4b1f4bSPeter Holmexit 0
291