xref: /freebsd/tools/test/stress2/misc/syzkaller78.sh (revision abe84e61107639cdb5b7854ff74f9a5a91984e3d)
1*abe84e61SPeter Holm#!/bin/sh
2*abe84e61SPeter Holm
3*abe84e61SPeter Holm# Fatal trap 12: page fault while in kernel mode
4*abe84e61SPeter Holm# cpuid = 10; apic id = 07
5*abe84e61SPeter Holm# fault virtual address   = 0x0
6*abe84e61SPeter Holm# fault code              = supervisor read data, page not present
7*abe84e61SPeter Holm# instruction pointer     = 0x20:0xffffffff80c3c276
8*abe84e61SPeter Holm# stack pointer           = 0x28:0xfffffe017273eb00
9*abe84e61SPeter Holm# frame pointer           = 0x28:0xfffffe017273eb30
10*abe84e61SPeter Holm# code segment            = base 0x0, limit 0xfffff, type 0x1b
11*abe84e61SPeter Holm#                         = DPL 0, pres 1, long 1, def32 0, gran 1
12*abe84e61SPeter Holm# processor eflags        = interrupt enabled, resume, IOPL = 0
13*abe84e61SPeter Holm# current process         = 43905 (syzkaller78)
14*abe84e61SPeter Holm# rdi: fffff8005b5d55e0 rsi: 0000000000000008 rdx: ffffffff81249e88
15*abe84e61SPeter Holm# rcx: fffff8001b9aed00  r8: 0000000000000000  r9: fffff80003396000
16*abe84e61SPeter Holm# rax: 0000000000000000 rbx: fffff8005b5d5400 rbp: fffffe017273eb30
17*abe84e61SPeter Holm# r10: 0000000000000000 r11: fffff804d84e9c60 r12: fffff8005b5d55f8
18*abe84e61SPeter Holm# r13: 0000000000000000 r14: fffff80497171700 r15: fffff8005b5d55c0
19*abe84e61SPeter Holm# trap number             = 12
20*abe84e61SPeter Holm# panic: page fault
21*abe84e61SPeter Holm# cpuid = 7
22*abe84e61SPeter Holm# time = 1746555157
23*abe84e61SPeter Holm# KDB: stack backtrace:
24*abe84e61SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe017273e830
25*abe84e61SPeter Holm# vpanic() at vpanic+0x136/frame 0xfffffe017273e960
26*abe84e61SPeter Holm# panic() at panic+0x43/frame 0xfffffe017273e9c0
27*abe84e61SPeter Holm# trap_pfault() at trap_pfault+0x48d/frame 0xfffffe017273ea30
28*abe84e61SPeter Holm# calltrap() at calltrap+0x8/frame 0xfffffe017273ea30
29*abe84e61SPeter Holm# --- trap 0xc, rip = 0xffffffff80c3c276, rsp = 0xfffffe017273eb00, rbp = 0xfffffe017273eb30 ---
30*abe84e61SPeter Holm# unp_dispose() at unp_dispose+0x3b6/frame 0xfffffe017273eb30
31*abe84e61SPeter Holm# uipc_detach() at uipc_detach+0x35/frame 0xfffffe017273eb80
32*abe84e61SPeter Holm# sorele_locked() at sorele_locked+0x107/frame 0xfffffe017273ebb0
33*abe84e61SPeter Holm# soclose() at soclose+0x17d/frame 0xfffffe017273ec10
34*abe84e61SPeter Holm# _fdrop() at _fdrop+0x1b/frame 0xfffffe017273ec30
35*abe84e61SPeter Holm# closef() at closef+0x1e3/frame 0xfffffe017273ecc0
36*abe84e61SPeter Holm# fdescfree() at fdescfree+0x41e/frame 0xfffffe017273ed80
37*abe84e61SPeter Holm# exit1() at exit1+0x4a4/frame 0xfffffe017273edf0
38*abe84e61SPeter Holm# sys_exit() at sys_exit+0xd/frameamd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe017273ef30
39*abe84e61SPeter Holm# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe017273ef30
40*abe84e61SPeter Holm# --- syscall (1, FreeBSD ELF64, exit), rip = 0x823ab472a, rsp = 0x8208e3ea8, rbp = 0x8208e3ec0 ---
41*abe84e61SPeter Holm# KDB: enter: panic
42*abe84e61SPeter Holm# [ thread pid 43905 tid 103344 ]
43*abe84e61SPeter Holm# Stopped at      kdb_enter+0x33: movq    $0,0x122f202(%rip)
44*abe84e61SPeter Holm# db>
45*abe84e61SPeter Holm
46*abe84e61SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
47*abe84e61SPeter Holm
48*abe84e61SPeter Holm. ../default.cfg
49*abe84e61SPeter Holmset -u
50*abe84e61SPeter Holmprog=$(basename "$0" .sh)
51*abe84e61SPeter Holmcat > /tmp/$prog.c <<EOF
52*abe84e61SPeter Holm// https://syzkaller.appspot.com/bug?id=46eb92ee6e2f6acbd4250d0f2065b1f93296bd82
53*abe84e61SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller)
54*abe84e61SPeter Holm// syzbot+0e99ffc200638909ca1c@syzkaller.appspotmail.com
55*abe84e61SPeter Holm
56*abe84e61SPeter Holm#define _GNU_SOURCE
57*abe84e61SPeter Holm
58*abe84e61SPeter Holm#include <sys/types.h>
59*abe84e61SPeter Holm
60*abe84e61SPeter Holm#include <dirent.h>
61*abe84e61SPeter Holm#include <errno.h>
62*abe84e61SPeter Holm#include <pwd.h>
63*abe84e61SPeter Holm#include <signal.h>
64*abe84e61SPeter Holm#include <stdarg.h>
65*abe84e61SPeter Holm#include <stdbool.h>
66*abe84e61SPeter Holm#include <stdint.h>
67*abe84e61SPeter Holm#include <stdio.h>
68*abe84e61SPeter Holm#include <stdlib.h>
69*abe84e61SPeter Holm#include <string.h>
70*abe84e61SPeter Holm#include <sys/endian.h>
71*abe84e61SPeter Holm#include <sys/stat.h>
72*abe84e61SPeter Holm#include <sys/syscall.h>
73*abe84e61SPeter Holm#include <sys/wait.h>
74*abe84e61SPeter Holm#include <time.h>
75*abe84e61SPeter Holm#include <unistd.h>
76*abe84e61SPeter Holm
77*abe84e61SPeter Holmstatic unsigned long long procid;
78*abe84e61SPeter Holm
79*abe84e61SPeter Holmstatic void kill_and_wait(int pid, int* status)
80*abe84e61SPeter Holm{
81*abe84e61SPeter Holm  kill(pid, SIGKILL);
82*abe84e61SPeter Holm  while (waitpid(-1, status, 0) != pid) {
83*abe84e61SPeter Holm  }
84*abe84e61SPeter Holm}
85*abe84e61SPeter Holm
86*abe84e61SPeter Holmstatic void sleep_ms(uint64_t ms)
87*abe84e61SPeter Holm{
88*abe84e61SPeter Holm  usleep(ms * 1000);
89*abe84e61SPeter Holm}
90*abe84e61SPeter Holm
91*abe84e61SPeter Holmstatic uint64_t current_time_ms(void)
92*abe84e61SPeter Holm{
93*abe84e61SPeter Holm  struct timespec ts;
94*abe84e61SPeter Holm  if (clock_gettime(CLOCK_MONOTONIC, &ts))
95*abe84e61SPeter Holm    exit(1);
96*abe84e61SPeter Holm  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
97*abe84e61SPeter Holm}
98*abe84e61SPeter Holm
99*abe84e61SPeter Holmstatic void use_temporary_dir(void)
100*abe84e61SPeter Holm{
101*abe84e61SPeter Holm  char tmpdir_template[] = "./syzkaller.XXXXXX";
102*abe84e61SPeter Holm  char* tmpdir = mkdtemp(tmpdir_template);
103*abe84e61SPeter Holm  if (!tmpdir)
104*abe84e61SPeter Holm    exit(1);
105*abe84e61SPeter Holm  if (chmod(tmpdir, 0777))
106*abe84e61SPeter Holm    exit(1);
107*abe84e61SPeter Holm  if (chdir(tmpdir))
108*abe84e61SPeter Holm    exit(1);
109*abe84e61SPeter Holm}
110*abe84e61SPeter Holm
111*abe84e61SPeter Holmstatic void reset_flags(const char* filename)
112*abe84e61SPeter Holm{
113*abe84e61SPeter Holm  struct stat st;
114*abe84e61SPeter Holm  if (lstat(filename, &st))
115*abe84e61SPeter Holm    exit(1);
116*abe84e61SPeter Holm  st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE |
117*abe84e61SPeter Holm                   SF_APPEND | UF_APPEND);
118*abe84e61SPeter Holm  if (lchflags(filename, st.st_flags))
119*abe84e61SPeter Holm    exit(1);
120*abe84e61SPeter Holm}
121*abe84e61SPeter Holmstatic void __attribute__((noinline)) remove_dir(const char* dir)
122*abe84e61SPeter Holm{
123*abe84e61SPeter Holm  DIR* dp = opendir(dir);
124*abe84e61SPeter Holm  if (dp == NULL) {
125*abe84e61SPeter Holm    if (errno == EACCES) {
126*abe84e61SPeter Holm      if (rmdir(dir))
127*abe84e61SPeter Holm        exit(1);
128*abe84e61SPeter Holm      return;
129*abe84e61SPeter Holm    }
130*abe84e61SPeter Holm    exit(1);
131*abe84e61SPeter Holm  }
132*abe84e61SPeter Holm  struct dirent* ep = 0;
133*abe84e61SPeter Holm  while ((ep = readdir(dp))) {
134*abe84e61SPeter Holm    if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
135*abe84e61SPeter Holm      continue;
136*abe84e61SPeter Holm    char filename[FILENAME_MAX];
137*abe84e61SPeter Holm    snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
138*abe84e61SPeter Holm    struct stat st;
139*abe84e61SPeter Holm    if (lstat(filename, &st))
140*abe84e61SPeter Holm      exit(1);
141*abe84e61SPeter Holm    if (S_ISDIR(st.st_mode)) {
142*abe84e61SPeter Holm      remove_dir(filename);
143*abe84e61SPeter Holm      continue;
144*abe84e61SPeter Holm    }
145*abe84e61SPeter Holm    if (unlink(filename)) {
146*abe84e61SPeter Holm      if (errno == EPERM) {
147*abe84e61SPeter Holm        reset_flags(filename);
148*abe84e61SPeter Holm        reset_flags(dir);
149*abe84e61SPeter Holm        if (unlink(filename) == 0)
150*abe84e61SPeter Holm          continue;
151*abe84e61SPeter Holm      }
152*abe84e61SPeter Holm      exit(1);
153*abe84e61SPeter Holm    }
154*abe84e61SPeter Holm  }
155*abe84e61SPeter Holm  closedir(dp);
156*abe84e61SPeter Holm  while (rmdir(dir)) {
157*abe84e61SPeter Holm    if (errno == EPERM) {
158*abe84e61SPeter Holm      reset_flags(dir);
159*abe84e61SPeter Holm      if (rmdir(dir) == 0)
160*abe84e61SPeter Holm        break;
161*abe84e61SPeter Holm    }
162*abe84e61SPeter Holm    exit(1);
163*abe84e61SPeter Holm  }
164*abe84e61SPeter Holm}
165*abe84e61SPeter Holm
166*abe84e61SPeter Holmstatic void execute_one(void);
167*abe84e61SPeter Holm
168*abe84e61SPeter Holm#define WAIT_FLAGS 0
169*abe84e61SPeter Holm
170*abe84e61SPeter Holmstatic void loop(void)
171*abe84e61SPeter Holm{
172*abe84e61SPeter Holm  int iter = 0;
173*abe84e61SPeter Holm  for (;; iter++) {
174*abe84e61SPeter Holm    char cwdbuf[32];
175*abe84e61SPeter Holm    sprintf(cwdbuf, "./%d", iter);
176*abe84e61SPeter Holm    if (mkdir(cwdbuf, 0777))
177*abe84e61SPeter Holm      exit(1);
178*abe84e61SPeter Holm    int pid = fork();
179*abe84e61SPeter Holm    if (pid < 0)
180*abe84e61SPeter Holm      exit(1);
181*abe84e61SPeter Holm    if (pid == 0) {
182*abe84e61SPeter Holm      if (chdir(cwdbuf))
183*abe84e61SPeter Holm        exit(1);
184*abe84e61SPeter Holm      execute_one();
185*abe84e61SPeter Holm      exit(0);
186*abe84e61SPeter Holm    }
187*abe84e61SPeter Holm    int status = 0;
188*abe84e61SPeter Holm    uint64_t start = current_time_ms();
189*abe84e61SPeter Holm    for (;;) {
190*abe84e61SPeter Holm      sleep_ms(10);
191*abe84e61SPeter Holm      if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
192*abe84e61SPeter Holm        break;
193*abe84e61SPeter Holm      if (current_time_ms() - start < 5000)
194*abe84e61SPeter Holm        continue;
195*abe84e61SPeter Holm      kill_and_wait(pid, &status);
196*abe84e61SPeter Holm      break;
197*abe84e61SPeter Holm    }
198*abe84e61SPeter Holm    remove_dir(cwdbuf);
199*abe84e61SPeter Holm  }
200*abe84e61SPeter Holm}
201*abe84e61SPeter Holm
202*abe84e61SPeter Holmuint64_t r[5] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
203*abe84e61SPeter Holm                 0xffffffffffffffff, 0xffffffffffffffff};
204*abe84e61SPeter Holm
205*abe84e61SPeter Holmvoid execute_one(void)
206*abe84e61SPeter Holm{
207*abe84e61SPeter Holm  intptr_t res = 0;
208*abe84e61SPeter Holm  if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
209*abe84e61SPeter Holm  }
210*abe84e61SPeter Holm  memcpy((void*)0x200000000480, "./file0\000", 8);
211*abe84e61SPeter Holm  res = syscall(
212*abe84e61SPeter Holm      SYS_open, /*file=*/0x200000000480ul,
213*abe84e61SPeter Holm      /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80000000000000*/ 0x80000000000206ul,
214*abe84e61SPeter Holm      /*mode=*/0ul);
215*abe84e61SPeter Holm  if (res != -1)
216*abe84e61SPeter Holm    r[0] = res;
217*abe84e61SPeter Holm  syscall(SYS_ftruncate, /*fd=*/r[0], /*len=*/0x3862ul);
218*abe84e61SPeter Holm  memcpy((void*)0x200000000100, "./file0\000", 8);
219*abe84e61SPeter Holm  res = syscall(SYS_open, /*file=*/0x200000000100ul,
220*abe84e61SPeter Holm                /*flags=O_DIRECT*/ 0x10000ul, /*mode=*/0ul);
221*abe84e61SPeter Holm  if (res != -1)
222*abe84e61SPeter Holm    r[1] = res;
223*abe84e61SPeter Holm  *(uint64_t*)0x2000000000c0 = 0x200000000340;
224*abe84e61SPeter Holm  *(uint64_t*)0x2000000000c8 = 0x41;
225*abe84e61SPeter Holm  syscall(SYS_readv, /*fd=*/r[1], /*vec=*/0x2000000000c0ul, /*vlen=*/1ul);
226*abe84e61SPeter Holm  res = syscall(SYS_socket, /*domain=*/2ul, /*type=*/2ul, /*proto=*/0x88);
227*abe84e61SPeter Holm  if (res != -1)
228*abe84e61SPeter Holm    r[2] = res;
229*abe84e61SPeter Holm  res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul,
230*abe84e61SPeter Holm                /*proto=*/0, /*fds=*/0x200000000180ul);
231*abe84e61SPeter Holm  if (res != -1)
232*abe84e61SPeter Holm    r[3] = *(uint32_t*)0x200000000180;
233*abe84e61SPeter Holm  syscall(SYS_dup2, /*oldfd=*/r[3], /*newfd=*/r[2]);
234*abe84e61SPeter Holm  memcpy((void*)0x200000000140, "./file0\000", 8);
235*abe84e61SPeter Holm  res =
236*abe84e61SPeter Holm      syscall(SYS_open, /*file=*/0x200000000140ul, /*flags=*/0ul, /*mode=*/0ul);
237*abe84e61SPeter Holm  if (res != -1)
238*abe84e61SPeter Holm    r[4] = res;
239*abe84e61SPeter Holm  syscall(SYS_sendfile, /*fd=*/r[4], /*s=*/r[2], /*offset=*/0xcbul,
240*abe84e61SPeter Holm          /*nbytes=*/0x2000ul, /*hdtr=*/0ul, /*sbytes=*/0ul,
241*abe84e61SPeter Holm          /*flags=SF_USER_READAHEAD|SF_NODISKIO|0x2*/ 0xbul);
242*abe84e61SPeter Holm}
243*abe84e61SPeter Holmint main(void)
244*abe84e61SPeter Holm{
245*abe84e61SPeter Holm  syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
246*abe84e61SPeter Holm          /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
247*abe84e61SPeter Holm          /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
248*abe84e61SPeter Holm          /*fd=*/(intptr_t)-1, /*offset=*/0ul);
249*abe84e61SPeter Holm  const char* reason;
250*abe84e61SPeter Holm  (void)reason;
251*abe84e61SPeter Holm  for (procid = 0; procid < 4; procid++) {
252*abe84e61SPeter Holm    if (fork() == 0) {
253*abe84e61SPeter Holm      use_temporary_dir();
254*abe84e61SPeter Holm      loop();
255*abe84e61SPeter Holm    }
256*abe84e61SPeter Holm  }
257*abe84e61SPeter Holm  sleep(1000000);
258*abe84e61SPeter Holm  return 0;
259*abe84e61SPeter Holm}
260*abe84e61SPeter HolmEOF
261*abe84e61SPeter Holmmycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
262*abe84e61SPeter Holm
263*abe84e61SPeter Holm(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) &
264*abe84e61SPeter Holmsleep 5
265*abe84e61SPeter Holm
266*abe84e61SPeter Holmwork=/tmp/$prog.dir
267*abe84e61SPeter Holmrm -rf $work
268*abe84e61SPeter Holmmkdir $work
269*abe84e61SPeter Holmcd /tmp/$prog.dir
270*abe84e61SPeter Holmfor i in `jot 30`; do
271*abe84e61SPeter Holm	(
272*abe84e61SPeter Holm		mkdir d$i
273*abe84e61SPeter Holm		cd d$i
274*abe84e61SPeter Holm		timeout 3m /tmp/$prog > /dev/null 2>&1 &
275*abe84e61SPeter Holm	)
276*abe84e61SPeter Holmdone
277*abe84e61SPeter Holmwhile pgrep -q $prog; do sleep 2; done
278*abe84e61SPeter Holmwhile pkill swap; do :; done
279*abe84e61SPeter Holmwait
280*abe84e61SPeter Holm
281*abe84e61SPeter Holmrm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
282*abe84e61SPeter Holmexit 0
283