xref: /freebsd/tools/test/stress2/misc/syzkaller49.sh (revision dfc383201f97272e4307bc90b82dc7ed870fc54a)
1*dfc38320SPeter Holm#!/bin/sh
2*dfc38320SPeter Holm
3*dfc38320SPeter Holm# Fatal trap 12: page fault while in kernel mode
4*dfc38320SPeter Holm# cpuid = 10; apic id = 0a
5*dfc38320SPeter Holm# fault virtual address   = 0x0
6*dfc38320SPeter Holm# fault code              = supervisor read data, page not present
7*dfc38320SPeter Holm# instruction pointer     = 0x20:0xffffffff80e04f35
8*dfc38320SPeter Holm# stack pointer           = 0x28:0xfffffe014fd0fbc0
9*dfc38320SPeter Holm# frame pointer           = 0x28:0xfffffe014fd0fc00
10*dfc38320SPeter Holm# code segment            = base 0x0, limit 0xfffff, type 0x1b
11*dfc38320SPeter Holm#                         = DPL 0, pres 1, long 1, def32 0, gran 1
12*dfc38320SPeter Holm# processor eflags        = interrupt enabled, resume, IOPL = 0
13*dfc38320SPeter Holm# current process         = 13332 (repro77)
14*dfc38320SPeter Holm# trap number             = 12
15*dfc38320SPeter Holm# panic: page fault
16*dfc38320SPeter Holm# cpuid = 10
17*dfc38320SPeter Holm# time = 1640585179
18*dfc38320SPeter Holm# KDB: stack backtrace:
19*dfc38320SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe014fd0f980
20*dfc38320SPeter Holm# vpanic() at vpanic+0x17f/frame 0xfffffe014fd0f9d0
21*dfc38320SPeter Holm# panic() at panic+0x43/frame 0xfffffe014fd0fa30
22*dfc38320SPeter Holm# trap_fatal() at trap_fatal+0x385/frame 0xfffffe014fd0fa90
23*dfc38320SPeter Holm# trap_pfault() at trap_pfault+0xab/frame 0xfffffe014fd0faf0
24*dfc38320SPeter Holm# calltrap() at calltrap+0x8/frame 0xfffffe014fd0faf0
25*dfc38320SPeter Holm# --- trap 0xc, rip = 0xffffffff80e04f35, rsp = 0xfffffe014fd0fbc0, rbp = 0xfffffe014fd0fc00 ---
26*dfc38320SPeter Holm# tcp_usr_rcvd() at tcp_usr_rcvd+0x65/frame 0xfffffe014fd0fc00
27*dfc38320SPeter Holm# soreceive_generic() at soreceive_generic+0xe44/frame 0xfffffe014fd0fcc0
28*dfc38320SPeter Holm# soreceive() at soreceive+0x4b/frame 0xfffffe014fd0fce0
29*dfc38320SPeter Holm# kern_recvit() at kern_recvit+0x1ba/frame 0xfffffe014fd0fd90
30*dfc38320SPeter Holm# sys_recvmsg() at sys_recvmsg+0x6f/frame 0xfffffe014fd0fe00
31*dfc38320SPeter Holm# amd64_syscall() at amd64_syscall+0x145/frame 0xfffffe014fd0ff30
32*dfc38320SPeter Holm# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe014fd0ff30
33*dfc38320SPeter Holm# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x8020e328a, rsp = 0x22f48, rbp = 0x22f70 ---
34*dfc38320SPeter Holm# KDB: enter: panic
35*dfc38320SPeter Holm# [ thread pid 13332 tid 103311 ]
36*dfc38320SPeter Holm# Stopped at      kdb_enter+0x37: movq    $0,0x128720e(%rip)
37*dfc38320SPeter Holm# db> x/s version
38*dfc38320SPeter Holm# version: FreeBSD 14.0-CURRENT #0 ufs-n251956-c3008785b91: Mon Dec 27 06:11:30 CET 2021
39*dfc38320SPeter Holm# pho@mercat1.netperf.freebsd.org:/var/tmp/deviant3/sys/amd64/compile/PHO
40*dfc38320SPeter Holm# db>
41*dfc38320SPeter Holm
42*dfc38320SPeter Holm. ../default.cfg
43*dfc38320SPeter Holm[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
44*dfc38320SPeter Holm
45*dfc38320SPeter Holmcat > /tmp/syzkaller49.c <<EOF
46*dfc38320SPeter Holm// https://syzkaller.appspot.com/bug?id=efb2e9f019f36fbc39380724a31cb0c458bb4e61
47*dfc38320SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller)
48*dfc38320SPeter Holm// Reported-by: syzbot+93c75c4618b2a4f0f0ac@syzkaller.appspotmail.com
49*dfc38320SPeter Holm
50*dfc38320SPeter Holm#define _GNU_SOURCE
51*dfc38320SPeter Holm
52*dfc38320SPeter Holm#include <errno.h>
53*dfc38320SPeter Holm#include <pthread.h>
54*dfc38320SPeter Holm#include <pwd.h>
55*dfc38320SPeter Holm#include <stdarg.h>
56*dfc38320SPeter Holm#include <stdbool.h>
57*dfc38320SPeter Holm#include <stdint.h>
58*dfc38320SPeter Holm#include <stdio.h>
59*dfc38320SPeter Holm#include <stdlib.h>
60*dfc38320SPeter Holm#include <string.h>
61*dfc38320SPeter Holm#include <sys/endian.h>
62*dfc38320SPeter Holm#include <sys/syscall.h>
63*dfc38320SPeter Holm#include <time.h>
64*dfc38320SPeter Holm#include <unistd.h>
65*dfc38320SPeter Holm
66*dfc38320SPeter Holmstatic void sleep_ms(uint64_t ms)
67*dfc38320SPeter Holm{
68*dfc38320SPeter Holm  usleep(ms * 1000);
69*dfc38320SPeter Holm}
70*dfc38320SPeter Holm
71*dfc38320SPeter Holmstatic uint64_t current_time_ms(void)
72*dfc38320SPeter Holm{
73*dfc38320SPeter Holm  struct timespec ts;
74*dfc38320SPeter Holm  if (clock_gettime(CLOCK_MONOTONIC, &ts))
75*dfc38320SPeter Holm    exit(1);
76*dfc38320SPeter Holm  return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
77*dfc38320SPeter Holm}
78*dfc38320SPeter Holm
79*dfc38320SPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg)
80*dfc38320SPeter Holm{
81*dfc38320SPeter Holm  pthread_t th;
82*dfc38320SPeter Holm  pthread_attr_t attr;
83*dfc38320SPeter Holm  pthread_attr_init(&attr);
84*dfc38320SPeter Holm  pthread_attr_setstacksize(&attr, 128 << 10);
85*dfc38320SPeter Holm  int i = 0;
86*dfc38320SPeter Holm  for (; i < 100; i++) {
87*dfc38320SPeter Holm    if (pthread_create(&th, &attr, fn, arg) == 0) {
88*dfc38320SPeter Holm      pthread_attr_destroy(&attr);
89*dfc38320SPeter Holm      return;
90*dfc38320SPeter Holm    }
91*dfc38320SPeter Holm    if (errno == EAGAIN) {
92*dfc38320SPeter Holm      usleep(50);
93*dfc38320SPeter Holm      continue;
94*dfc38320SPeter Holm    }
95*dfc38320SPeter Holm    break;
96*dfc38320SPeter Holm  }
97*dfc38320SPeter Holm  exit(1);
98*dfc38320SPeter Holm}
99*dfc38320SPeter Holm
100*dfc38320SPeter Holmtypedef struct {
101*dfc38320SPeter Holm  pthread_mutex_t mu;
102*dfc38320SPeter Holm  pthread_cond_t cv;
103*dfc38320SPeter Holm  int state;
104*dfc38320SPeter Holm} event_t;
105*dfc38320SPeter Holm
106*dfc38320SPeter Holmstatic void event_init(event_t* ev)
107*dfc38320SPeter Holm{
108*dfc38320SPeter Holm  if (pthread_mutex_init(&ev->mu, 0))
109*dfc38320SPeter Holm    exit(1);
110*dfc38320SPeter Holm  if (pthread_cond_init(&ev->cv, 0))
111*dfc38320SPeter Holm    exit(1);
112*dfc38320SPeter Holm  ev->state = 0;
113*dfc38320SPeter Holm}
114*dfc38320SPeter Holm
115*dfc38320SPeter Holmstatic void event_reset(event_t* ev)
116*dfc38320SPeter Holm{
117*dfc38320SPeter Holm  ev->state = 0;
118*dfc38320SPeter Holm}
119*dfc38320SPeter Holm
120*dfc38320SPeter Holmstatic void event_set(event_t* ev)
121*dfc38320SPeter Holm{
122*dfc38320SPeter Holm  pthread_mutex_lock(&ev->mu);
123*dfc38320SPeter Holm  if (ev->state)
124*dfc38320SPeter Holm    exit(1);
125*dfc38320SPeter Holm  ev->state = 1;
126*dfc38320SPeter Holm  pthread_mutex_unlock(&ev->mu);
127*dfc38320SPeter Holm  pthread_cond_broadcast(&ev->cv);
128*dfc38320SPeter Holm}
129*dfc38320SPeter Holm
130*dfc38320SPeter Holmstatic void event_wait(event_t* ev)
131*dfc38320SPeter Holm{
132*dfc38320SPeter Holm  pthread_mutex_lock(&ev->mu);
133*dfc38320SPeter Holm  while (!ev->state)
134*dfc38320SPeter Holm    pthread_cond_wait(&ev->cv, &ev->mu);
135*dfc38320SPeter Holm  pthread_mutex_unlock(&ev->mu);
136*dfc38320SPeter Holm}
137*dfc38320SPeter Holm
138*dfc38320SPeter Holmstatic int event_isset(event_t* ev)
139*dfc38320SPeter Holm{
140*dfc38320SPeter Holm  pthread_mutex_lock(&ev->mu);
141*dfc38320SPeter Holm  int res = ev->state;
142*dfc38320SPeter Holm  pthread_mutex_unlock(&ev->mu);
143*dfc38320SPeter Holm  return res;
144*dfc38320SPeter Holm}
145*dfc38320SPeter Holm
146*dfc38320SPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout)
147*dfc38320SPeter Holm{
148*dfc38320SPeter Holm  uint64_t start = current_time_ms();
149*dfc38320SPeter Holm  uint64_t now = start;
150*dfc38320SPeter Holm  pthread_mutex_lock(&ev->mu);
151*dfc38320SPeter Holm  for (;;) {
152*dfc38320SPeter Holm    if (ev->state)
153*dfc38320SPeter Holm      break;
154*dfc38320SPeter Holm    uint64_t remain = timeout - (now - start);
155*dfc38320SPeter Holm    struct timespec ts;
156*dfc38320SPeter Holm    ts.tv_sec = remain / 1000;
157*dfc38320SPeter Holm    ts.tv_nsec = (remain % 1000) * 1000 * 1000;
158*dfc38320SPeter Holm    pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
159*dfc38320SPeter Holm    now = current_time_ms();
160*dfc38320SPeter Holm    if (now - start > timeout)
161*dfc38320SPeter Holm      break;
162*dfc38320SPeter Holm  }
163*dfc38320SPeter Holm  int res = ev->state;
164*dfc38320SPeter Holm  pthread_mutex_unlock(&ev->mu);
165*dfc38320SPeter Holm  return res;
166*dfc38320SPeter Holm}
167*dfc38320SPeter Holm
168*dfc38320SPeter Holmstruct thread_t {
169*dfc38320SPeter Holm  int created, call;
170*dfc38320SPeter Holm  event_t ready, done;
171*dfc38320SPeter Holm};
172*dfc38320SPeter Holm
173*dfc38320SPeter Holmstatic struct thread_t threads[16];
174*dfc38320SPeter Holmstatic void execute_call(int call);
175*dfc38320SPeter Holmstatic int running;
176*dfc38320SPeter Holm
177*dfc38320SPeter Holmstatic void* thr(void* arg)
178*dfc38320SPeter Holm{
179*dfc38320SPeter Holm  struct thread_t* th = (struct thread_t*)arg;
180*dfc38320SPeter Holm  for (;;) {
181*dfc38320SPeter Holm    event_wait(&th->ready);
182*dfc38320SPeter Holm    event_reset(&th->ready);
183*dfc38320SPeter Holm    execute_call(th->call);
184*dfc38320SPeter Holm    __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
185*dfc38320SPeter Holm    event_set(&th->done);
186*dfc38320SPeter Holm  }
187*dfc38320SPeter Holm  return 0;
188*dfc38320SPeter Holm}
189*dfc38320SPeter Holm
190*dfc38320SPeter Holmstatic void loop(void)
191*dfc38320SPeter Holm{
192*dfc38320SPeter Holm  int i, call, thread;
193*dfc38320SPeter Holm  for (call = 0; call < 6; call++) {
194*dfc38320SPeter Holm    for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
195*dfc38320SPeter Holm         thread++) {
196*dfc38320SPeter Holm      struct thread_t* th = &threads[thread];
197*dfc38320SPeter Holm      if (!th->created) {
198*dfc38320SPeter Holm        th->created = 1;
199*dfc38320SPeter Holm        event_init(&th->ready);
200*dfc38320SPeter Holm        event_init(&th->done);
201*dfc38320SPeter Holm        event_set(&th->done);
202*dfc38320SPeter Holm        thread_start(thr, th);
203*dfc38320SPeter Holm      }
204*dfc38320SPeter Holm      if (!event_isset(&th->done))
205*dfc38320SPeter Holm        continue;
206*dfc38320SPeter Holm      event_reset(&th->done);
207*dfc38320SPeter Holm      th->call = call;
208*dfc38320SPeter Holm      __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
209*dfc38320SPeter Holm      event_set(&th->ready);
210*dfc38320SPeter Holm      event_timedwait(&th->done, 50);
211*dfc38320SPeter Holm      break;
212*dfc38320SPeter Holm    }
213*dfc38320SPeter Holm  }
214*dfc38320SPeter Holm  for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
215*dfc38320SPeter Holm    sleep_ms(1);
216*dfc38320SPeter Holm}
217*dfc38320SPeter Holm
218*dfc38320SPeter Holmuint64_t r[1] = {0xffffffffffffffff};
219*dfc38320SPeter Holm
220*dfc38320SPeter Holmvoid execute_call(int call)
221*dfc38320SPeter Holm{
222*dfc38320SPeter Holm  intptr_t res = 0;
223*dfc38320SPeter Holm  switch (call) {
224*dfc38320SPeter Holm  case 0:
225*dfc38320SPeter Holm    res = syscall(SYS_socket, 2ul, 1ul, 0);
226*dfc38320SPeter Holm    if (res != -1)
227*dfc38320SPeter Holm      r[0] = res;
228*dfc38320SPeter Holm    break;
229*dfc38320SPeter Holm  case 1:
230*dfc38320SPeter Holm    *(uint8_t*)0x20000140 = 0x10;
231*dfc38320SPeter Holm    *(uint8_t*)0x20000141 = 2;
232*dfc38320SPeter Holm    *(uint16_t*)0x20000142 = htobe16(0x4e23);
233*dfc38320SPeter Holm    *(uint32_t*)0x20000144 = htobe32(0x7f000001);
234*dfc38320SPeter Holm    memset((void*)0x20000148, 0, 8);
235*dfc38320SPeter Holm    syscall(SYS_bind, r[0], 0x20000140ul, 0x10ul);
236*dfc38320SPeter Holm    break;
237*dfc38320SPeter Holm  case 2:
238*dfc38320SPeter Holm    *(uint8_t*)0x20000080 = 0x10;
239*dfc38320SPeter Holm    *(uint8_t*)0x20000081 = 2;
240*dfc38320SPeter Holm    *(uint16_t*)0x20000082 = htobe16(0x4e23);
241*dfc38320SPeter Holm    *(uint32_t*)0x20000084 = htobe32(0x7f000001);
242*dfc38320SPeter Holm    memset((void*)0x20000088, 0, 8);
243*dfc38320SPeter Holm    syscall(SYS_sendto, r[0], 0ul, 0ul, 0ul, 0x20000080ul, 0x10ul);
244*dfc38320SPeter Holm    break;
245*dfc38320SPeter Holm  case 3:
246*dfc38320SPeter Holm    memset((void*)0x20000100, 69, 1);
247*dfc38320SPeter Holm    syscall(SYS_sendto, r[0], 0x20000100ul, 0xfda4ul, 0ul, 0ul, 0ul);
248*dfc38320SPeter Holm    break;
249*dfc38320SPeter Holm  case 4:
250*dfc38320SPeter Holm    *(uint64_t*)0x200003c0 = 0;
251*dfc38320SPeter Holm    *(uint32_t*)0x200003c8 = 0;
252*dfc38320SPeter Holm    *(uint64_t*)0x200003d0 = 0x20000340;
253*dfc38320SPeter Holm    *(uint64_t*)0x20000340 = 0x20000680;
254*dfc38320SPeter Holm    *(uint64_t*)0x20000348 = 0x19000;
255*dfc38320SPeter Holm    *(uint64_t*)0x200003d8 = 1;
256*dfc38320SPeter Holm    *(uint64_t*)0x200003e0 = 0;
257*dfc38320SPeter Holm    *(uint64_t*)0x200003e8 = 0;
258*dfc38320SPeter Holm    *(uint32_t*)0x200003f0 = 0;
259*dfc38320SPeter Holm    syscall(SYS_recvmsg, r[0], 0x200003c0ul, 0x40ul);
260*dfc38320SPeter Holm    break;
261*dfc38320SPeter Holm  case 5:
262*dfc38320SPeter Holm    syscall(SYS_shutdown, r[0], 1ul);
263*dfc38320SPeter Holm    break;
264*dfc38320SPeter Holm  }
265*dfc38320SPeter Holm}
266*dfc38320SPeter Holmint main(void)
267*dfc38320SPeter Holm{
268*dfc38320SPeter Holm  syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
269*dfc38320SPeter Holm  loop();
270*dfc38320SPeter Holm  return 0;
271*dfc38320SPeter Holm}
272*dfc38320SPeter HolmEOF
273*dfc38320SPeter Holm
274*dfc38320SPeter Holmset -e
275*dfc38320SPeter Holmmount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
276*dfc38320SPeter Holm[ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
277*dfc38320SPeter Holmmdconfig -a -t swap -s 5g -u $mdstart
278*dfc38320SPeter Holmnewfs $newfs_flags -n md$mdstart > /dev/null
279*dfc38320SPeter Holmmount /dev/md$mdstart $mntpoint
280*dfc38320SPeter Holmset +e
281*dfc38320SPeter Holm
282*dfc38320SPeter Holmmkdir $mntpoint/work
283*dfc38320SPeter Holmmycc -o $mntpoint/work/syzkaller49 -Wall -Wextra -O0 /tmp/syzkaller49.c -lpthread || exit 1
284*dfc38320SPeter Holm
285*dfc38320SPeter Holmstart=`date +%s`
286*dfc38320SPeter Holmwhile [ $((`date +%s` - start)) -lt 120 ]; do
287*dfc38320SPeter Holm	(cd $mntpoint/work; ./syzkaller49)
288*dfc38320SPeter Holmdone
289*dfc38320SPeter Holm
290*dfc38320SPeter Holmfor i in `jot 6`; do
291*dfc38320SPeter Holm	mount | grep -q "on $mntpoint " || break
292*dfc38320SPeter Holm	umount $mntpoint && break || sleep 10
293*dfc38320SPeter Holm	[ $i -eq 6 ] &&
294*dfc38320SPeter Holm	    { echo FATAL; fstat -mf $mntpoint; exit 1; }
295*dfc38320SPeter Holmdone
296*dfc38320SPeter Holmmdconfig -d -u $mdstart
297*dfc38320SPeter Holm
298*dfc38320SPeter Holmrm -rf /tmp/syzkaller49.c
299*dfc38320SPeter Holmexit 0
300