xref: /freebsd/tools/test/stress2/misc/syzkaller28.sh (revision 2a58b312b62f908ec92311d1bd8536dbaeb8e55b)
1#!/bin/sh
2
3# panic: About to free ctl:0xfffff809b0ac1260 so:0xfffff80d97dde760 and its in 1
4# cpuid = 9
5# time = 1605860285
6# KDB: stack backtrace:
7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0100b1e630
8# vpanic() at vpanic+0x182/frame 0xfffffe0100b1e680
9# panic() at panic+0x43/frame 0xfffffe0100b1e6e0
10# sctp_sorecvmsg() at sctp_sorecvmsg+0x1a96/frame 0xfffffe0100b1e810
11# sctp_soreceive() at sctp_soreceive+0x1b2/frame 0xfffffe0100b1ea00
12# soreceive() at soreceive+0x59/frame 0xfffffe0100b1ea20
13# dofileread() at dofileread+0x81/frame 0xfffffe0100b1ea70
14# sys_readv() at sys_readv+0x6e/frame 0xfffffe0100b1eac0
15# amd64_syscall() at amd64_syscall+0x147/frame 0xfffffe0100b1ebf0
16# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0100b1ebf0
17# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x8003aed4a, rsp = 0x7fffdfffdf68, rbp = 0x7fffdfffdf90 ---
18# KDB: enter: panic
19# [ thread pid 3933 tid 102941 ]
20# Stopped at      kdb_enter+0x37: movq    $0,0x10a91b6(%rip)
21# db> x/s version
22# version: FreeBSD 13.0-CURRENT #0 r367842: Thu Nov 19 13:08:17 CET 2020
23# pho@t2.osted.lan:/usr/src/sys/amd64/compile/PHO
24# db>
25
26[ `uname -p` != "amd64" ] && exit 0
27
28. ../default.cfg
29kldstat -v | grep -q sctp || kldload sctp.ko
30
31cat > /tmp/syzkaller28.c <<EOF
32// https://syzkaller.appspot.com/bug?id=b0e5bd1e2a4ac3caf8e2ad16ae6054d9fcc2e9d2
33// autogenerated by syzkaller (https://github.com/google/syzkaller)
34// Reported-by: syzbot+b2d3e3f439385340e35f@syzkaller.appspotmail.com
35
36#define _GNU_SOURCE
37
38#include <sys/types.h>
39
40#include <errno.h>
41#include <pthread.h>
42#include <pwd.h>
43#include <signal.h>
44#include <stdarg.h>
45#include <stdbool.h>
46#include <stdint.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <sys/endian.h>
51#include <sys/syscall.h>
52#include <sys/wait.h>
53#include <time.h>
54#include <unistd.h>
55
56static unsigned long long procid;
57
58static void kill_and_wait(int pid, int* status)
59{
60  kill(pid, SIGKILL);
61  while (waitpid(-1, status, 0) != pid) {
62  }
63}
64
65static void sleep_ms(uint64_t ms)
66{
67  usleep(ms * 1000);
68}
69
70static uint64_t current_time_ms(void)
71{
72  struct timespec ts;
73  if (clock_gettime(CLOCK_MONOTONIC, &ts))
74    exit(1);
75  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
76}
77
78static void thread_start(void* (*fn)(void*), void* arg)
79{
80  pthread_t th;
81  pthread_attr_t attr;
82  pthread_attr_init(&attr);
83  pthread_attr_setstacksize(&attr, 128 << 10);
84  int i = 0;
85  for (; i < 100; i++) {
86    if (pthread_create(&th, &attr, fn, arg) == 0) {
87      pthread_attr_destroy(&attr);
88      return;
89    }
90    if (errno == EAGAIN) {
91      usleep(50);
92      continue;
93    }
94    break;
95  }
96  exit(1);
97}
98
99typedef struct {
100  pthread_mutex_t mu;
101  pthread_cond_t cv;
102  int state;
103} event_t;
104
105static void event_init(event_t* ev)
106{
107  if (pthread_mutex_init(&ev->mu, 0))
108    exit(1);
109  if (pthread_cond_init(&ev->cv, 0))
110    exit(1);
111  ev->state = 0;
112}
113
114static void event_reset(event_t* ev)
115{
116  ev->state = 0;
117}
118
119static void event_set(event_t* ev)
120{
121  pthread_mutex_lock(&ev->mu);
122  if (ev->state)
123    exit(1);
124  ev->state = 1;
125  pthread_mutex_unlock(&ev->mu);
126  pthread_cond_broadcast(&ev->cv);
127}
128
129static void event_wait(event_t* ev)
130{
131  pthread_mutex_lock(&ev->mu);
132  while (!ev->state)
133    pthread_cond_wait(&ev->cv, &ev->mu);
134  pthread_mutex_unlock(&ev->mu);
135}
136
137static int event_isset(event_t* ev)
138{
139  pthread_mutex_lock(&ev->mu);
140  int res = ev->state;
141  pthread_mutex_unlock(&ev->mu);
142  return res;
143}
144
145static int event_timedwait(event_t* ev, uint64_t timeout)
146{
147  uint64_t start = current_time_ms();
148  uint64_t now = start;
149  pthread_mutex_lock(&ev->mu);
150  for (;;) {
151    if (ev->state)
152      break;
153    uint64_t remain = timeout - (now - start);
154    struct timespec ts;
155    ts.tv_sec = remain / 1000;
156    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
157    pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
158    now = current_time_ms();
159    if (now - start > timeout)
160      break;
161  }
162  int res = ev->state;
163  pthread_mutex_unlock(&ev->mu);
164  return res;
165}
166
167struct thread_t {
168  int created, call;
169  event_t ready, done;
170};
171
172static struct thread_t threads[16];
173static void execute_call(int call);
174static int running;
175
176static void* thr(void* arg)
177{
178  struct thread_t* th = (struct thread_t*)arg;
179  for (;;) {
180    event_wait(&th->ready);
181    event_reset(&th->ready);
182    execute_call(th->call);
183    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
184    event_set(&th->done);
185  }
186  return 0;
187}
188
189static void execute_one(void)
190{
191  int i, call, thread;
192  for (call = 0; call < 9; call++) {
193    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
194         thread++) {
195      struct thread_t* th = &threads[thread];
196      if (!th->created) {
197        th->created = 1;
198        event_init(&th->ready);
199        event_init(&th->done);
200        event_set(&th->done);
201        thread_start(thr, th);
202      }
203      if (!event_isset(&th->done))
204        continue;
205      event_reset(&th->done);
206      th->call = call;
207      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
208      event_set(&th->ready);
209      event_timedwait(&th->done, 45);
210      break;
211    }
212  }
213  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
214    sleep_ms(1);
215}
216
217static void execute_one(void);
218
219#define WAIT_FLAGS 0
220
221static void loop(void)
222{
223  int iter = 0;
224  for (;; iter++) {
225    int pid = fork();
226    if (pid < 0)
227      exit(1);
228    if (pid == 0) {
229      execute_one();
230      exit(0);
231    }
232    int status = 0;
233    uint64_t start = current_time_ms();
234    for (;;) {
235      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
236        break;
237      sleep_ms(1);
238      if (current_time_ms() - start < 5 * 1000)
239        continue;
240      kill_and_wait(pid, &status);
241      break;
242    }
243  }
244}
245
246uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
247
248void execute_call(int call)
249{
250  intptr_t res = 0;
251  switch (call) {
252  case 0:
253    res = syscall(SYS_socket, 0x1cul, 1ul, 0x84);
254    if (res != -1)
255      r[0] = res;
256    break;
257  case 1:
258    *(uint32_t*)0x20000040 = 0;
259    syscall(SYS_setsockopt, r[0], 0x84, 0x11, 0x20000040ul, 4ul);
260    break;
261  case 2:
262    *(uint8_t*)0x20000000 = 0x1c;
263    *(uint8_t*)0x20000001 = 0x1c;
264    *(uint16_t*)0x20000002 = htobe16(0x4e22 + procid * 4);
265    *(uint32_t*)0x20000004 = 0;
266    *(uint8_t*)0x20000008 = 0;
267    *(uint8_t*)0x20000009 = 0;
268    *(uint8_t*)0x2000000a = 0;
269    *(uint8_t*)0x2000000b = 0;
270    *(uint8_t*)0x2000000c = 0;
271    *(uint8_t*)0x2000000d = 0;
272    *(uint8_t*)0x2000000e = 0;
273    *(uint8_t*)0x2000000f = 0;
274    *(uint8_t*)0x20000010 = 0;
275    *(uint8_t*)0x20000011 = 0;
276    *(uint8_t*)0x20000012 = 0;
277    *(uint8_t*)0x20000013 = 0;
278    *(uint8_t*)0x20000014 = 0;
279    *(uint8_t*)0x20000015 = 0;
280    *(uint8_t*)0x20000016 = 0;
281    *(uint8_t*)0x20000017 = 0;
282    *(uint32_t*)0x20000018 = 6;
283    syscall(SYS_bind, r[0], 0x20000000ul, 0x1cul);
284    break;
285  case 3:
286    *(uint8_t*)0x20000180 = 0x5f;
287    *(uint8_t*)0x20000181 = 0x1c;
288    *(uint16_t*)0x20000182 = htobe16(0x4e22 + procid * 4);
289    *(uint32_t*)0x20000184 = 0;
290    *(uint64_t*)0x20000188 = htobe64(0);
291    *(uint64_t*)0x20000190 = htobe64(1);
292    *(uint32_t*)0x20000198 = 0;
293    syscall(SYS_connect, r[0], 0x20000180ul, 0x1cul);
294    break;
295  case 4:
296    *(uint64_t*)0x20001500 = 0x20000200;
297    *(uint64_t*)0x20001508 = 0xb8;
298    *(uint64_t*)0x20001510 = 0;
299    *(uint64_t*)0x20001518 = 0;
300    *(uint64_t*)0x20001520 = 0;
301    *(uint64_t*)0x20001528 = 0;
302    *(uint64_t*)0x20001530 = 0;
303    *(uint64_t*)0x20001538 = 0;
304    *(uint64_t*)0x20001540 = 0;
305    *(uint64_t*)0x20001548 = 0;
306    syscall(SYS_readv, r[0], 0x20001500ul, 5ul);
307    break;
308  case 5:
309    *(uint32_t*)0x20000140 = 0xb2;
310    syscall(SYS_setsockopt, r[0], 0x84, 0x1b, 0x20000140ul, 4ul);
311    break;
312  case 6:
313    res = syscall(SYS_fcntl, r[0], 0ul, r[0]);
314    if (res != -1)
315      r[1] = res;
316    break;
317  case 7:
318    *(uint64_t*)0x200004c0 = 0;
319    *(uint32_t*)0x200004c8 = 0;
320    *(uint64_t*)0x200004d0 = 0x200003c0;
321    *(uint64_t*)0x200003c0 = 0x200001c0;
322    memcpy((void*)0x200001c0, "\xb0", 1);
323    *(uint64_t*)0x200003c8 = 1;
324    *(uint32_t*)0x200004d8 = 1;
325    *(uint64_t*)0x200004e0 = 0;
326    *(uint32_t*)0x200004e8 = 0;
327    *(uint32_t*)0x200004ec = 0;
328    syscall(SYS_sendmsg, r[1], 0x200004c0ul, 0ul);
329    break;
330  case 8:
331    syscall(SYS_shutdown, r[0], 1ul);
332    break;
333  }
334}
335int main(void)
336{
337  syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
338  for (procid = 0; procid < 4; procid++) {
339    if (fork() == 0) {
340      loop();
341    }
342  }
343  sleep(1000000);
344  return 0;
345}
346EOF
347mycc -o /tmp/syzkaller28 -Wall -Wextra -O0 /tmp/syzkaller28.c -lpthread ||
348    exit 1
349
350(cd ../testcases/swap; ./swap -t 1m -i 20 -h > /dev/null 2>&1) &
351(cd /tmp; timeout 3m ./syzkaller28)
352while pkill swap; do :; done
353wait
354
355rm -rf /tmp/syzkaller28 /tmp/syzkaller28.c /tmp/syzkaller.*
356exit 0
357