xref: /freebsd/tools/test/stress2/misc/syzkaller39.sh (revision b3b695604de3304f4f71506dccb70a1d06f44026)
1*b3b69560SPeter Holm#!/bin/sh
2*b3b69560SPeter Holm
3*b3b69560SPeter Holm# panic: ktrace_enter: flag set
4*b3b69560SPeter Holm# cpuid = 0
5*b3b69560SPeter Holm# time = 1621577415
6*b3b69560SPeter Holm# KDB: stack backtrace:
7*b3b69560SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01c0025670
8*b3b69560SPeter Holm# vpanic() at vpanic+0x181/frame 0xfffffe01c00256c0
9*b3b69560SPeter Holm# panic() at panic+0x43/frame 0xfffffe01c0025720
10*b3b69560SPeter Holm# ktrnamei() at ktrnamei+0xdb/frame 0xfffffe01c0025750
11*b3b69560SPeter Holm# namei() at namei+0x805/frame 0xfffffe01c0025800
12*b3b69560SPeter Holm# vn_open_cred() at vn_open_cred+0x497/frame 0xfffffe01c0025970
13*b3b69560SPeter Holm# sys_ktrace() at sys_ktrace+0x1a0/frame 0xfffffe01c0025ac0
14*b3b69560SPeter Holm# amd64_syscall() at amd64_syscall+0x147/frame 0xfffffe01c0025bf0
15*b3b69560SPeter Holm# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01c0025bf0
16*b3b69560SPeter Holm# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x8003b054a, rsp = 0x7fffdfffdf68, rbp = 0x7fffdfffdf90 ---
17*b3b69560SPeter Holm# KDB: enter: panic
18*b3b69560SPeter Holm# [ thread pid 80729 tid 101297 ]
19*b3b69560SPeter Holm# Stopped at      kdb_enter+0x37: movq    $0,0x1281d9e(%rip)
20*b3b69560SPeter Holm# db> x/s version
21*b3b69560SPeter Holm# version: FreeBSD 14.0-CURRENT #0 main-n246739-fc0dc94029d-dirty: Wed May 19 05:54:45 CEST 2021
22*b3b69560SPeter Holm# pho@t2.osted.lan:/usr/src/sys/amd64/compile/PHO
23*b3b69560SPeter Holm# db>
24*b3b69560SPeter Holm
25*b3b69560SPeter Holm[ `uname -p` != "amd64" ] && exit 0
26*b3b69560SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
27*b3b69560SPeter Holm
28*b3b69560SPeter Holm. ../default.cfg
29*b3b69560SPeter Holmcat > /tmp/syzkaller39.c <<EOF
30*b3b69560SPeter Holm// https://syzkaller.appspot.com/bug?id=01d7251d81bbf2bf91279ecc73897961cd72beea
31*b3b69560SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller)
32*b3b69560SPeter Holm// Reported-by: syzbot+d0a4de45e58d3c08af4b@syzkaller.appspotmail.com
33*b3b69560SPeter Holm
34*b3b69560SPeter Holm#define _GNU_SOURCE
35*b3b69560SPeter Holm
36*b3b69560SPeter Holm#include <errno.h>
37*b3b69560SPeter Holm#include <pthread.h>
38*b3b69560SPeter Holm#include <pwd.h>
39*b3b69560SPeter Holm#include <stdarg.h>
40*b3b69560SPeter Holm#include <stdbool.h>
41*b3b69560SPeter Holm#include <stdint.h>
42*b3b69560SPeter Holm#include <stdio.h>
43*b3b69560SPeter Holm#include <stdlib.h>
44*b3b69560SPeter Holm#include <string.h>
45*b3b69560SPeter Holm#include <sys/endian.h>
46*b3b69560SPeter Holm#include <sys/syscall.h>
47*b3b69560SPeter Holm#include <time.h>
48*b3b69560SPeter Holm#include <unistd.h>
49*b3b69560SPeter Holm
50*b3b69560SPeter Holmstatic void sleep_ms(uint64_t ms)
51*b3b69560SPeter Holm{
52*b3b69560SPeter Holm  usleep(ms * 1000);
53*b3b69560SPeter Holm}
54*b3b69560SPeter Holm
55*b3b69560SPeter Holmstatic uint64_t current_time_ms(void)
56*b3b69560SPeter Holm{
57*b3b69560SPeter Holm  struct timespec ts;
58*b3b69560SPeter Holm  if (clock_gettime(CLOCK_MONOTONIC, &ts))
59*b3b69560SPeter Holm    exit(1);
60*b3b69560SPeter Holm  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
61*b3b69560SPeter Holm}
62*b3b69560SPeter Holm
63*b3b69560SPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg)
64*b3b69560SPeter Holm{
65*b3b69560SPeter Holm  pthread_t th;
66*b3b69560SPeter Holm  pthread_attr_t attr;
67*b3b69560SPeter Holm  pthread_attr_init(&attr);
68*b3b69560SPeter Holm  pthread_attr_setstacksize(&attr, 128 << 10);
69*b3b69560SPeter Holm  int i = 0;
70*b3b69560SPeter Holm  for (; i < 100; i++) {
71*b3b69560SPeter Holm    if (pthread_create(&th, &attr, fn, arg) == 0) {
72*b3b69560SPeter Holm      pthread_attr_destroy(&attr);
73*b3b69560SPeter Holm      return;
74*b3b69560SPeter Holm    }
75*b3b69560SPeter Holm    if (errno == EAGAIN) {
76*b3b69560SPeter Holm      usleep(50);
77*b3b69560SPeter Holm      continue;
78*b3b69560SPeter Holm    }
79*b3b69560SPeter Holm    break;
80*b3b69560SPeter Holm  }
81*b3b69560SPeter Holm  exit(1);
82*b3b69560SPeter Holm}
83*b3b69560SPeter Holm
84*b3b69560SPeter Holmtypedef struct {
85*b3b69560SPeter Holm  pthread_mutex_t mu;
86*b3b69560SPeter Holm  pthread_cond_t cv;
87*b3b69560SPeter Holm  int state;
88*b3b69560SPeter Holm} event_t;
89*b3b69560SPeter Holm
90*b3b69560SPeter Holmstatic void event_init(event_t* ev)
91*b3b69560SPeter Holm{
92*b3b69560SPeter Holm  if (pthread_mutex_init(&ev->mu, 0))
93*b3b69560SPeter Holm    exit(1);
94*b3b69560SPeter Holm  if (pthread_cond_init(&ev->cv, 0))
95*b3b69560SPeter Holm    exit(1);
96*b3b69560SPeter Holm  ev->state = 0;
97*b3b69560SPeter Holm}
98*b3b69560SPeter Holm
99*b3b69560SPeter Holmstatic void event_reset(event_t* ev)
100*b3b69560SPeter Holm{
101*b3b69560SPeter Holm  ev->state = 0;
102*b3b69560SPeter Holm}
103*b3b69560SPeter Holm
104*b3b69560SPeter Holmstatic void event_set(event_t* ev)
105*b3b69560SPeter Holm{
106*b3b69560SPeter Holm  pthread_mutex_lock(&ev->mu);
107*b3b69560SPeter Holm  if (ev->state)
108*b3b69560SPeter Holm    exit(1);
109*b3b69560SPeter Holm  ev->state = 1;
110*b3b69560SPeter Holm  pthread_mutex_unlock(&ev->mu);
111*b3b69560SPeter Holm  pthread_cond_broadcast(&ev->cv);
112*b3b69560SPeter Holm}
113*b3b69560SPeter Holm
114*b3b69560SPeter Holmstatic void event_wait(event_t* ev)
115*b3b69560SPeter Holm{
116*b3b69560SPeter Holm  pthread_mutex_lock(&ev->mu);
117*b3b69560SPeter Holm  while (!ev->state)
118*b3b69560SPeter Holm    pthread_cond_wait(&ev->cv, &ev->mu);
119*b3b69560SPeter Holm  pthread_mutex_unlock(&ev->mu);
120*b3b69560SPeter Holm}
121*b3b69560SPeter Holm
122*b3b69560SPeter Holmstatic int event_isset(event_t* ev)
123*b3b69560SPeter Holm{
124*b3b69560SPeter Holm  pthread_mutex_lock(&ev->mu);
125*b3b69560SPeter Holm  int res = ev->state;
126*b3b69560SPeter Holm  pthread_mutex_unlock(&ev->mu);
127*b3b69560SPeter Holm  return res;
128*b3b69560SPeter Holm}
129*b3b69560SPeter Holm
130*b3b69560SPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout)
131*b3b69560SPeter Holm{
132*b3b69560SPeter Holm  uint64_t start = current_time_ms();
133*b3b69560SPeter Holm  uint64_t now = start;
134*b3b69560SPeter Holm  pthread_mutex_lock(&ev->mu);
135*b3b69560SPeter Holm  for (;;) {
136*b3b69560SPeter Holm    if (ev->state)
137*b3b69560SPeter Holm      break;
138*b3b69560SPeter Holm    uint64_t remain = timeout - (now - start);
139*b3b69560SPeter Holm    struct timespec ts;
140*b3b69560SPeter Holm    ts.tv_sec = remain / 1000;
141*b3b69560SPeter Holm    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
142*b3b69560SPeter Holm    pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
143*b3b69560SPeter Holm    now = current_time_ms();
144*b3b69560SPeter Holm    if (now - start > timeout)
145*b3b69560SPeter Holm      break;
146*b3b69560SPeter Holm  }
147*b3b69560SPeter Holm  int res = ev->state;
148*b3b69560SPeter Holm  pthread_mutex_unlock(&ev->mu);
149*b3b69560SPeter Holm  return res;
150*b3b69560SPeter Holm}
151*b3b69560SPeter Holm
152*b3b69560SPeter Holmstruct thread_t {
153*b3b69560SPeter Holm  int created, call;
154*b3b69560SPeter Holm  event_t ready, done;
155*b3b69560SPeter Holm};
156*b3b69560SPeter Holm
157*b3b69560SPeter Holmstatic struct thread_t threads[16];
158*b3b69560SPeter Holmstatic void execute_call(int call);
159*b3b69560SPeter Holmstatic int running;
160*b3b69560SPeter Holm
161*b3b69560SPeter Holmstatic void* thr(void* arg)
162*b3b69560SPeter Holm{
163*b3b69560SPeter Holm  struct thread_t* th = (struct thread_t*)arg;
164*b3b69560SPeter Holm  for (;;) {
165*b3b69560SPeter Holm    event_wait(&th->ready);
166*b3b69560SPeter Holm    event_reset(&th->ready);
167*b3b69560SPeter Holm    execute_call(th->call);
168*b3b69560SPeter Holm    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
169*b3b69560SPeter Holm    event_set(&th->done);
170*b3b69560SPeter Holm  }
171*b3b69560SPeter Holm  return 0;
172*b3b69560SPeter Holm}
173*b3b69560SPeter Holm
174*b3b69560SPeter Holmstatic void loop(void)
175*b3b69560SPeter Holm{
176*b3b69560SPeter Holm  int i, call, thread;
177*b3b69560SPeter Holm  int collide = 0;
178*b3b69560SPeter Holmagain:
179*b3b69560SPeter Holm  for (call = 0; call < 3; call++) {
180*b3b69560SPeter Holm    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
181*b3b69560SPeter Holm         thread++) {
182*b3b69560SPeter Holm      struct thread_t* th = &threads[thread];
183*b3b69560SPeter Holm      if (!th->created) {
184*b3b69560SPeter Holm        th->created = 1;
185*b3b69560SPeter Holm        event_init(&th->ready);
186*b3b69560SPeter Holm        event_init(&th->done);
187*b3b69560SPeter Holm        event_set(&th->done);
188*b3b69560SPeter Holm        thread_start(thr, th);
189*b3b69560SPeter Holm      }
190*b3b69560SPeter Holm      if (!event_isset(&th->done))
191*b3b69560SPeter Holm        continue;
192*b3b69560SPeter Holm      event_reset(&th->done);
193*b3b69560SPeter Holm      th->call = call;
194*b3b69560SPeter Holm      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
195*b3b69560SPeter Holm      event_set(&th->ready);
196*b3b69560SPeter Holm      if (collide && (call % 2) == 0)
197*b3b69560SPeter Holm        break;
198*b3b69560SPeter Holm      event_timedwait(&th->done, 50);
199*b3b69560SPeter Holm      break;
200*b3b69560SPeter Holm    }
201*b3b69560SPeter Holm  }
202*b3b69560SPeter Holm  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
203*b3b69560SPeter Holm    sleep_ms(1);
204*b3b69560SPeter Holm  if (!collide) {
205*b3b69560SPeter Holm    collide = 1;
206*b3b69560SPeter Holm    goto again;
207*b3b69560SPeter Holm  }
208*b3b69560SPeter Holm}
209*b3b69560SPeter Holm
210*b3b69560SPeter Holmuint64_t r[1] = {0x0};
211*b3b69560SPeter Holm
212*b3b69560SPeter Holmvoid execute_call(int call)
213*b3b69560SPeter Holm{
214*b3b69560SPeter Holm  intptr_t res = 0;
215*b3b69560SPeter Holm  switch (call) {
216*b3b69560SPeter Holm  case 0:
217*b3b69560SPeter Holm    memcpy((void*)0x20000140, "./file0\000", 8);
218*b3b69560SPeter Holm    syscall(SYS_open, 0x20000140ul, 0x200ul, 0ul);
219*b3b69560SPeter Holm    break;
220*b3b69560SPeter Holm  case 1:
221*b3b69560SPeter Holm    res = syscall(SYS_getpid);
222*b3b69560SPeter Holm    if (res != -1)
223*b3b69560SPeter Holm      r[0] = res;
224*b3b69560SPeter Holm    break;
225*b3b69560SPeter Holm  case 2:
226*b3b69560SPeter Holm    memcpy((void*)0x20000040, "./file0\000", 8);
227*b3b69560SPeter Holm    syscall(SYS_ktrace, 0x20000040ul, 0ul, 0x4722db8820f38dbbul, r[0]);
228*b3b69560SPeter Holm    break;
229*b3b69560SPeter Holm  }
230*b3b69560SPeter Holm}
231*b3b69560SPeter Holmint main(void)
232*b3b69560SPeter Holm{
233*b3b69560SPeter Holm  syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
234*b3b69560SPeter Holm  loop();
235*b3b69560SPeter Holm  return 0;
236*b3b69560SPeter Holm}
237*b3b69560SPeter HolmEOF
238*b3b69560SPeter Holmmycc -o /tmp/syzkaller39 -Wall -Wextra -O0 /tmp/syzkaller39.c -lpthread ||
239*b3b69560SPeter Holm    exit 1
240*b3b69560SPeter Holm
241*b3b69560SPeter Holm(cd /tmp; timeout 3m ./syzkaller39)
242*b3b69560SPeter Holm
243*b3b69560SPeter Holmrm -rf /tmp/syzkaller39 syzkaller39.c /tmp/syzkaller.*
244*b3b69560SPeter Holmexit 0
245