xref: /freebsd/tools/test/stress2/misc/syzkaller77.sh (revision abe84e61107639cdb5b7854ff74f9a5a91984e3d)
1#!/bin/sh
2
3# panic: sofree:1883 curvnet is NULL, so=0xfffff8017ca59000
4# cpuid = 8
5# time = 1746559098
6# KDB: stack backtrace:
7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0182b5c8d0
8# vpanic() at vpanic+0x136/frame 0xfffffe0182b5ca00
9# panic() at panic+0x43/frame 0xfffffe0182b5ca60
10# sorele_locked() at sorele_locked+0x25f/frame 0xfffffe0182b5ca90
11# uipc_sendfile_wait() at uipc_sendfile_wait+0x1df/frame 0xfffffe0182b5caf0
12# vn_sendfile() at vn_sendfile+0x59b/frame 0xfffffe0182b5cd70
13# sendfile() at sendfile+0x129/frame 0xfffffe0182b5ce00
14# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe0182b5cf30
15# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0182b5cf30
16# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x8223fb72a, rsp = 0x824baaf58, rbp = 0x824baaf90 ---
17# KDB: enter: panic
18# [ thread pid 6382 tid 103296 ]
19# Stopped at      kdb_enter+0x33: movq    $0,0x122f202(%rip)
20# db> x/s version
21# version: FreeBSD 15.0-CURRENT #0 main-n277057-794e792121ba-dirty: Tue May  6 18:34:20 CEST 2025
22# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
23# db>
24
25[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
26
27. ../default.cfg
28set -u
29prog=$(basename "$0" .sh)
30cat > /tmp/$prog.c <<EOF
31// https://syzkaller.appspot.com/bug?id=f04b36c4f2b84533225a1bd695a0aed2efa559e5
32// autogenerated by syzkaller (https://github.com/google/syzkaller)
33// syzbot+7b0b20cf2c672c181d98@syzkaller.appspotmail.com
34
35#define _GNU_SOURCE
36
37#include <errno.h>
38#include <pthread.h>
39#include <pwd.h>
40#include <stdarg.h>
41#include <stdbool.h>
42#include <stdint.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <sys/endian.h>
47#include <sys/syscall.h>
48#include <time.h>
49#include <unistd.h>
50
51static void sleep_ms(uint64_t ms)
52{
53  usleep(ms * 1000);
54}
55
56static uint64_t current_time_ms(void)
57{
58  struct timespec ts;
59  if (clock_gettime(CLOCK_MONOTONIC, &ts))
60    exit(1);
61  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
62}
63
64static void thread_start(void* (*fn)(void*), void* arg)
65{
66  pthread_t th;
67  pthread_attr_t attr;
68  pthread_attr_init(&attr);
69  pthread_attr_setstacksize(&attr, 128 << 10);
70  int i = 0;
71  for (; i < 100; i++) {
72    if (pthread_create(&th, &attr, fn, arg) == 0) {
73      pthread_attr_destroy(&attr);
74      return;
75    }
76    if (errno == EAGAIN) {
77      usleep(50);
78      continue;
79    }
80    break;
81  }
82  exit(1);
83}
84
85typedef struct {
86  pthread_mutex_t mu;
87  pthread_cond_t cv;
88  int state;
89} event_t;
90
91static void event_init(event_t* ev)
92{
93  if (pthread_mutex_init(&ev->mu, 0))
94    exit(1);
95  if (pthread_cond_init(&ev->cv, 0))
96    exit(1);
97  ev->state = 0;
98}
99
100static void event_reset(event_t* ev)
101{
102  ev->state = 0;
103}
104
105static void event_set(event_t* ev)
106{
107  pthread_mutex_lock(&ev->mu);
108  if (ev->state)
109    exit(1);
110  ev->state = 1;
111  pthread_mutex_unlock(&ev->mu);
112  pthread_cond_broadcast(&ev->cv);
113}
114
115static void event_wait(event_t* ev)
116{
117  pthread_mutex_lock(&ev->mu);
118  while (!ev->state)
119    pthread_cond_wait(&ev->cv, &ev->mu);
120  pthread_mutex_unlock(&ev->mu);
121}
122
123static int event_isset(event_t* ev)
124{
125  pthread_mutex_lock(&ev->mu);
126  int res = ev->state;
127  pthread_mutex_unlock(&ev->mu);
128  return res;
129}
130
131static int event_timedwait(event_t* ev, uint64_t timeout)
132{
133  uint64_t start = current_time_ms();
134  uint64_t now = start;
135  pthread_mutex_lock(&ev->mu);
136  for (;;) {
137    if (ev->state)
138      break;
139    uint64_t remain = timeout - (now - start);
140    struct timespec ts;
141    ts.tv_sec = remain / 1000;
142    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
143    pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
144    now = current_time_ms();
145    if (now - start > timeout)
146      break;
147  }
148  int res = ev->state;
149  pthread_mutex_unlock(&ev->mu);
150  return res;
151}
152
153struct thread_t {
154  int created, call;
155  event_t ready, done;
156};
157
158static struct thread_t threads[16];
159static void execute_call(int call);
160static int running;
161
162static void* thr(void* arg)
163{
164  struct thread_t* th = (struct thread_t*)arg;
165  for (;;) {
166    event_wait(&th->ready);
167    event_reset(&th->ready);
168    execute_call(th->call);
169    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
170    event_set(&th->done);
171  }
172  return 0;
173}
174
175static void loop(void)
176{
177  if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
178  }
179  int i, call, thread;
180  for (call = 0; call < 8; call++) {
181    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
182         thread++) {
183      struct thread_t* th = &threads[thread];
184      if (!th->created) {
185        th->created = 1;
186        event_init(&th->ready);
187        event_init(&th->done);
188        event_set(&th->done);
189        thread_start(thr, th);
190      }
191      if (!event_isset(&th->done))
192        continue;
193      event_reset(&th->done);
194      th->call = call;
195      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
196      event_set(&th->ready);
197      event_timedwait(&th->done, 50);
198      break;
199    }
200  }
201  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
202    sleep_ms(1);
203}
204
205uint64_t r[5] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
206                 0xffffffffffffffff, 0xffffffffffffffff};
207
208void execute_call(int call)
209{
210  intptr_t res = 0;
211  switch (call) {
212  case 0:
213    memcpy((void*)0x200000000480, "./file0\000", 8);
214    res = syscall(
215        SYS_open, /*file=*/0x200000000480ul,
216        /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80000000000000*/ 0x80000000000206ul,
217        /*mode=*/0ul);
218    if (res != -1)
219      r[0] = res;
220    break;
221  case 1:
222    syscall(SYS_ftruncate, /*fd=*/r[0], /*len=*/0x3862ul);
223    break;
224  case 2:
225    res = syscall(SYS_socket, /*domain=*/2ul, /*type=*/2ul, /*proto=*/0x88);
226    if (res != -1)
227      r[1] = res;
228    break;
229  case 3:
230    res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul,
231                  /*proto=*/0, /*fds=*/0x200000000180ul);
232    if (res != -1) {
233      r[2] = *(uint32_t*)0x200000000180;
234      r[3] = *(uint32_t*)0x200000000184;
235    }
236    break;
237  case 4:
238    syscall(SYS_dup2, /*oldfd=*/r[2], /*newfd=*/r[1]);
239    break;
240  case 5:
241    memcpy((void*)0x200000000140, "./file0\000", 8);
242    res = syscall(SYS_open, /*file=*/0x200000000140ul, /*flags=*/0ul,
243                  /*mode=*/0ul);
244    if (res != -1)
245      r[4] = res;
246    break;
247  case 6:
248    syscall(SYS_sendfile, /*fd=*/r[4], /*s=*/r[1], /*offset=*/0ul,
249            /*nbytes=*/0ul, /*hdtr=*/0ul, /*sbytes=*/0ul,
250            /*flags=SF_SYNC|SF_NOCACHE*/ 0x14ul);
251    break;
252  case 7:
253    syscall(SYS_dup2, /*oldfd=*/r[4], /*newfd=*/r[3]);
254    break;
255  }
256}
257int main(void)
258{
259  syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
260          /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
261          /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
262          /*fd=*/(intptr_t)-1, /*offset=*/0ul);
263  const char* reason;
264  (void)reason;
265  loop();
266  return 0;
267}
268EOF
269mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
270
271(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) &
272sleep 5
273
274work=/tmp/$prog.dir
275rm -rf $work
276mkdir $work
277cd /tmp/$prog.dir
278for i in `jot 30`; do
279	(
280		mkdir d$i
281		cd d$i
282		timeout 3m /tmp/$prog > /dev/null 2>&1 &
283	)
284done
285while pgrep -q $prog; do sleep 2; done
286while pkill swap; do :; done
287wait
288
289rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
290exit 0
291