xref: /freebsd/tools/test/stress2/misc/syzkaller14.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
1*8a272653SPeter Holm#!/bin/sh
2*8a272653SPeter Holm
3*8a272653SPeter Holm# panic: mtx_lock() of spin mutex (null) @ ../../../kern/uipc_ktls.c:1034
4*8a272653SPeter Holm# cpuid = 5
5*8a272653SPeter Holm# time = 1591684934
6*8a272653SPeter Holm# KDB: stack backtrace:
7*8a272653SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe013a91b6c0
8*8a272653SPeter Holm# vpanic() at vpanic+0x182/frame 0xfffffe013a91b710
9*8a272653SPeter Holm# panic() at panic+0x43/frame 0xfffffe013a91b770
10*8a272653SPeter Holm# __mtx_lock_flags() at __mtx_lock_flags+0x13c/frame 0xfffffe013a91b7c0
11*8a272653SPeter Holm# ktls_get_rx_mode() at ktls_get_rx_mode+0x4e/frame 0xfffffe013a91b7f0
12*8a272653SPeter Holm# tcp_default_ctloutput() at tcp_default_ctloutput+0x800/frame 0xfffffe013a91b960
13*8a272653SPeter Holm# tcp_ctloutput() at tcp_ctloutput+0x1f5/frame 0xfffffe013a91b9d0
14*8a272653SPeter Holm# sogetopt() at sogetopt+0x101/frame 0xfffffe013a91ba40
15*8a272653SPeter Holm# kern_getsockopt() at kern_getsockopt+0xb4/frame 0xfffffe013a91baa0
16*8a272653SPeter Holm# sys_getsockopt() at sys_getsockopt+0x52/frame 0xfffffe013a91bad0
17*8a272653SPeter Holm# amd64_syscall() at amd64_syscall+0x159/frame 0xfffffe013a91bbf0
18*8a272653SPeter Holm# fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe013a91bbf0
19*8a272653SPeter Holm# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x80045446a, rsp = 0x7fffdffdcf88, rbp = 0x7fffdffdcfc0 ---
20*8a272653SPeter Holm# KDB: enter: panic
21*8a272653SPeter Holm# [ thread pid 5313 tid 101679 ]
22*8a272653SPeter Holm# Stopped at      kdb_enter+0x37: movq    $0,0x10c7fa6(%rip)
23*8a272653SPeter Holm# db> x/s version
24*8a272653SPeter Holm# version:        FreeBSD 13.0-CURRENT #0 r361886: Tue Jun  9 08:32:24 CEST 2020\012    pho@t2.osted.lan:/usr/src/sys/amd64/compile/KTLS\012
25*8a272653SPeter Holm# db>
26*8a272653SPeter Holm
27*8a272653SPeter Holm# Reproduced on r361886 with "options KERN_TLS"
28*8a272653SPeter Holm
29*8a272653SPeter Holm[ `uname -p` = "i386" ] && exit 0
30*8a272653SPeter Holm
31*8a272653SPeter Holm. ../default.cfg
32*8a272653SPeter Holmcat > /tmp/syzkaller14.c <<EOF
33*8a272653SPeter Holm// https://syzkaller.appspot.com/bug?id=d50164ce557a20a785510aac5d6f104d8a62e779
34*8a272653SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller)
35*8a272653SPeter Holm// Reported-by: syzbot+a8829e888a93a4a04619@syzkaller.appspotmail.com
36*8a272653SPeter Holm
37*8a272653SPeter Holm#define _GNU_SOURCE
38*8a272653SPeter Holm
39*8a272653SPeter Holm#include <sys/types.h>
40*8a272653SPeter Holm
41*8a272653SPeter Holm#include <errno.h>
42*8a272653SPeter Holm#include <pthread.h>
43*8a272653SPeter Holm#include <pwd.h>
44*8a272653SPeter Holm#include <signal.h>
45*8a272653SPeter Holm#include <stdarg.h>
46*8a272653SPeter Holm#include <stdbool.h>
47*8a272653SPeter Holm#include <stdint.h>
48*8a272653SPeter Holm#include <stdio.h>
49*8a272653SPeter Holm#include <stdlib.h>
50*8a272653SPeter Holm#include <string.h>
51*8a272653SPeter Holm#include <sys/endian.h>
52*8a272653SPeter Holm#include <sys/syscall.h>
53*8a272653SPeter Holm#include <sys/wait.h>
54*8a272653SPeter Holm#include <time.h>
55*8a272653SPeter Holm#include <unistd.h>
56*8a272653SPeter Holm
57*8a272653SPeter Holmstatic unsigned long long procid;
58*8a272653SPeter Holm
59*8a272653SPeter Holmstatic void kill_and_wait(int pid, int* status)
60*8a272653SPeter Holm{
61*8a272653SPeter Holm  kill(pid, SIGKILL);
62*8a272653SPeter Holm  while (waitpid(-1, status, 0) != pid) {
63*8a272653SPeter Holm  }
64*8a272653SPeter Holm}
65*8a272653SPeter Holm
66*8a272653SPeter Holmstatic void sleep_ms(uint64_t ms)
67*8a272653SPeter Holm{
68*8a272653SPeter Holm  usleep(ms * 1000);
69*8a272653SPeter Holm}
70*8a272653SPeter Holm
71*8a272653SPeter Holmstatic uint64_t current_time_ms(void)
72*8a272653SPeter Holm{
73*8a272653SPeter Holm  struct timespec ts;
74*8a272653SPeter Holm  if (clock_gettime(CLOCK_MONOTONIC, &ts))
75*8a272653SPeter Holm    exit(1);
76*8a272653SPeter Holm  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
77*8a272653SPeter Holm}
78*8a272653SPeter Holm
79*8a272653SPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg)
80*8a272653SPeter Holm{
81*8a272653SPeter Holm  pthread_t th;
82*8a272653SPeter Holm  pthread_attr_t attr;
83*8a272653SPeter Holm  pthread_attr_init(&attr);
84*8a272653SPeter Holm  pthread_attr_setstacksize(&attr, 128 << 10);
85*8a272653SPeter Holm  int i;
86*8a272653SPeter Holm  for (i = 0; i < 100; i++) {
87*8a272653SPeter Holm    if (pthread_create(&th, &attr, fn, arg) == 0) {
88*8a272653SPeter Holm      pthread_attr_destroy(&attr);
89*8a272653SPeter Holm      return;
90*8a272653SPeter Holm    }
91*8a272653SPeter Holm    if (errno == EAGAIN) {
92*8a272653SPeter Holm      usleep(50);
93*8a272653SPeter Holm      continue;
94*8a272653SPeter Holm    }
95*8a272653SPeter Holm    break;
96*8a272653SPeter Holm  }
97*8a272653SPeter Holm  exit(1);
98*8a272653SPeter Holm}
99*8a272653SPeter Holm
100*8a272653SPeter Holmtypedef struct {
101*8a272653SPeter Holm  pthread_mutex_t mu;
102*8a272653SPeter Holm  pthread_cond_t cv;
103*8a272653SPeter Holm  int state;
104*8a272653SPeter Holm} event_t;
105*8a272653SPeter Holm
106*8a272653SPeter Holmstatic void event_init(event_t* ev)
107*8a272653SPeter Holm{
108*8a272653SPeter Holm  if (pthread_mutex_init(&ev->mu, 0))
109*8a272653SPeter Holm    exit(1);
110*8a272653SPeter Holm  if (pthread_cond_init(&ev->cv, 0))
111*8a272653SPeter Holm    exit(1);
112*8a272653SPeter Holm  ev->state = 0;
113*8a272653SPeter Holm}
114*8a272653SPeter Holm
115*8a272653SPeter Holmstatic void event_reset(event_t* ev)
116*8a272653SPeter Holm{
117*8a272653SPeter Holm  ev->state = 0;
118*8a272653SPeter Holm}
119*8a272653SPeter Holm
120*8a272653SPeter Holmstatic void event_set(event_t* ev)
121*8a272653SPeter Holm{
122*8a272653SPeter Holm  pthread_mutex_lock(&ev->mu);
123*8a272653SPeter Holm  if (ev->state)
124*8a272653SPeter Holm    exit(1);
125*8a272653SPeter Holm  ev->state = 1;
126*8a272653SPeter Holm  pthread_mutex_unlock(&ev->mu);
127*8a272653SPeter Holm  pthread_cond_broadcast(&ev->cv);
128*8a272653SPeter Holm}
129*8a272653SPeter Holm
130*8a272653SPeter Holmstatic void event_wait(event_t* ev)
131*8a272653SPeter Holm{
132*8a272653SPeter Holm  pthread_mutex_lock(&ev->mu);
133*8a272653SPeter Holm  while (!ev->state)
134*8a272653SPeter Holm    pthread_cond_wait(&ev->cv, &ev->mu);
135*8a272653SPeter Holm  pthread_mutex_unlock(&ev->mu);
136*8a272653SPeter Holm}
137*8a272653SPeter Holm
138*8a272653SPeter Holmstatic int event_isset(event_t* ev)
139*8a272653SPeter Holm{
140*8a272653SPeter Holm  pthread_mutex_lock(&ev->mu);
141*8a272653SPeter Holm  int res = ev->state;
142*8a272653SPeter Holm  pthread_mutex_unlock(&ev->mu);
143*8a272653SPeter Holm  return res;
144*8a272653SPeter Holm}
145*8a272653SPeter Holm
146*8a272653SPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout)
147*8a272653SPeter Holm{
148*8a272653SPeter Holm  uint64_t start = current_time_ms();
149*8a272653SPeter Holm  uint64_t now = start;
150*8a272653SPeter Holm  pthread_mutex_lock(&ev->mu);
151*8a272653SPeter Holm  for (;;) {
152*8a272653SPeter Holm    if (ev->state)
153*8a272653SPeter Holm      break;
154*8a272653SPeter Holm    uint64_t remain = timeout - (now - start);
155*8a272653SPeter Holm    struct timespec ts;
156*8a272653SPeter Holm    ts.tv_sec = remain / 1000;
157*8a272653SPeter Holm    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
158*8a272653SPeter Holm    pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
159*8a272653SPeter Holm    now = current_time_ms();
160*8a272653SPeter Holm    if (now - start > timeout)
161*8a272653SPeter Holm      break;
162*8a272653SPeter Holm  }
163*8a272653SPeter Holm  int res = ev->state;
164*8a272653SPeter Holm  pthread_mutex_unlock(&ev->mu);
165*8a272653SPeter Holm  return res;
166*8a272653SPeter Holm}
167*8a272653SPeter Holm
168*8a272653SPeter Holmstruct thread_t {
169*8a272653SPeter Holm  int created, call;
170*8a272653SPeter Holm  event_t ready, done;
171*8a272653SPeter Holm};
172*8a272653SPeter Holm
173*8a272653SPeter Holmstatic struct thread_t threads[16];
174*8a272653SPeter Holmstatic void execute_call(int call);
175*8a272653SPeter Holmstatic int running;
176*8a272653SPeter Holm
177*8a272653SPeter Holmstatic void* thr(void* arg)
178*8a272653SPeter Holm{
179*8a272653SPeter Holm  struct thread_t* th = (struct thread_t*)arg;
180*8a272653SPeter Holm  for (;;) {
181*8a272653SPeter Holm    event_wait(&th->ready);
182*8a272653SPeter Holm    event_reset(&th->ready);
183*8a272653SPeter Holm    execute_call(th->call);
184*8a272653SPeter Holm    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
185*8a272653SPeter Holm    event_set(&th->done);
186*8a272653SPeter Holm  }
187*8a272653SPeter Holm  return 0;
188*8a272653SPeter Holm}
189*8a272653SPeter Holm
190*8a272653SPeter Holmstatic void execute_one(void)
191*8a272653SPeter Holm{
192*8a272653SPeter Holm  int i, call, thread;
193*8a272653SPeter Holm  int collide = 0;
194*8a272653SPeter Holmagain:
195*8a272653SPeter Holm  for (call = 0; call < 3; call++) {
196*8a272653SPeter Holm    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
197*8a272653SPeter Holm         thread++) {
198*8a272653SPeter Holm      struct thread_t* th = &threads[thread];
199*8a272653SPeter Holm      if (!th->created) {
200*8a272653SPeter Holm        th->created = 1;
201*8a272653SPeter Holm        event_init(&th->ready);
202*8a272653SPeter Holm        event_init(&th->done);
203*8a272653SPeter Holm        event_set(&th->done);
204*8a272653SPeter Holm        thread_start(thr, th);
205*8a272653SPeter Holm      }
206*8a272653SPeter Holm      if (!event_isset(&th->done))
207*8a272653SPeter Holm        continue;
208*8a272653SPeter Holm      event_reset(&th->done);
209*8a272653SPeter Holm      th->call = call;
210*8a272653SPeter Holm      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
211*8a272653SPeter Holm      event_set(&th->ready);
212*8a272653SPeter Holm      if (collide && (call % 2) == 0)
213*8a272653SPeter Holm        break;
214*8a272653SPeter Holm      event_timedwait(&th->done, 45);
215*8a272653SPeter Holm      break;
216*8a272653SPeter Holm    }
217*8a272653SPeter Holm  }
218*8a272653SPeter Holm  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
219*8a272653SPeter Holm    sleep_ms(1);
220*8a272653SPeter Holm  if (!collide) {
221*8a272653SPeter Holm    collide = 1;
222*8a272653SPeter Holm    goto again;
223*8a272653SPeter Holm  }
224*8a272653SPeter Holm}
225*8a272653SPeter Holm
226*8a272653SPeter Holmstatic void execute_one(void);
227*8a272653SPeter Holm
228*8a272653SPeter Holm#define WAIT_FLAGS 0
229*8a272653SPeter Holm
230*8a272653SPeter Holmstatic void loop(void)
231*8a272653SPeter Holm{
232*8a272653SPeter Holm  int iter;
233*8a272653SPeter Holm  for (iter = 0;; iter++) {
234*8a272653SPeter Holm    int pid = fork();
235*8a272653SPeter Holm    if (pid < 0)
236*8a272653SPeter Holm      exit(1);
237*8a272653SPeter Holm    if (pid == 0) {
238*8a272653SPeter Holm      execute_one();
239*8a272653SPeter Holm      exit(0);
240*8a272653SPeter Holm    }
241*8a272653SPeter Holm    int status = 0;
242*8a272653SPeter Holm    uint64_t start = current_time_ms();
243*8a272653SPeter Holm    for (;;) {
244*8a272653SPeter Holm      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
245*8a272653SPeter Holm        break;
246*8a272653SPeter Holm      sleep_ms(1);
247*8a272653SPeter Holm      if (current_time_ms() - start < 5 * 1000)
248*8a272653SPeter Holm        continue;
249*8a272653SPeter Holm      kill_and_wait(pid, &status);
250*8a272653SPeter Holm      break;
251*8a272653SPeter Holm    }
252*8a272653SPeter Holm  }
253*8a272653SPeter Holm}
254*8a272653SPeter Holm
255*8a272653SPeter Holmuint64_t r[1] = {0xffffffffffffffff};
256*8a272653SPeter Holm
257*8a272653SPeter Holmvoid execute_call(int call)
258*8a272653SPeter Holm{
259*8a272653SPeter Holm  intptr_t res = 0;
260*8a272653SPeter Holm  switch (call) {
261*8a272653SPeter Holm  case 0:
262*8a272653SPeter Holm    res = syscall(SYS_socket, 0x1cul, 1ul, 0);
263*8a272653SPeter Holm    if (res != -1)
264*8a272653SPeter Holm      r[0] = res;
265*8a272653SPeter Holm    break;
266*8a272653SPeter Holm  case 1:
267*8a272653SPeter Holm    syscall(SYS_getsockopt, r[0], 6, 0x2a, 0ul, 0ul);
268*8a272653SPeter Holm    break;
269*8a272653SPeter Holm  case 2:
270*8a272653SPeter Holm    syscall(SYS_listen, r[0], 1);
271*8a272653SPeter Holm    break;
272*8a272653SPeter Holm  }
273*8a272653SPeter Holm}
274*8a272653SPeter Holmint main(void)
275*8a272653SPeter Holm{
276*8a272653SPeter Holm  syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
277*8a272653SPeter Holm  for (procid = 0; procid < 4; procid++) {
278*8a272653SPeter Holm    if (fork() == 0) {
279*8a272653SPeter Holm      loop();
280*8a272653SPeter Holm    }
281*8a272653SPeter Holm  }
282*8a272653SPeter Holm  sleep(1000000);
283*8a272653SPeter Holm  return 0;
284*8a272653SPeter Holm}
285*8a272653SPeter HolmEOF
286*8a272653SPeter Holmmycc -o /tmp/syzkaller14 -Wall -Wextra -O2 /tmp/syzkaller14.c -lpthread ||
287*8a272653SPeter Holm    exit 1
288*8a272653SPeter Holm
289*8a272653SPeter Holm(cd /tmp; ./syzkaller14) &
290*8a272653SPeter Holmsleep 60
291*8a272653SPeter Holmpkill -9 syzkaller14
292*8a272653SPeter Holmwait
293*8a272653SPeter Holm
294*8a272653SPeter Holmrm -f /tmp/syzkaller14 /tmp/syzkaller14.c /tmp/syzkaller14.core
295*8a272653SPeter Holmexit 0
296