xref: /freebsd/tools/test/stress2/misc/syzkaller89.sh (revision 833f9294b46856dce3028a8ecb65663ed422b629)
1#!/bin/sh
2
3# panic: MNT_DEFERRED requires MNT_RECURSE | MNT_FORCE
4# cpuid = 6
5# time = 1766415391
6# KDB: stack backtrace:
7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01003ffaf0
8# vpanic() at vpanic+0x136/frame 0xfffffe01003ffc20
9# panic() at panic+0x43/frame 0xfffffe01003ffc80
10# dounmount() at dounmount+0xa49/frame 0xfffffe01003ffcf0
11# kern_unmount() at kern_unmount+0x30c/frame 0xfffffe01003ffe00
12# amd64_syscall() at amd64_syscall+0x169/frame 0xfffffe01003fff30
13# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01003fff30
14# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x8227c1c1a, rsp = 0x8204589e8, rbp = 0x820458a50 ---
15# KDB: enter: panic
16# [ thread pid 67901 tid 1052310 ]
17# Stopped at      kdb_enter+0x33: movq    $0,0x12132c2(%rip)
18# db> x/s version
19# version:FreeBSD 16.0-CURRENT #1 vmfqe-n282663-949b0dac6c83: Sun Dec 21 12:59:23 CET 2025
20# pho@mercat1.netperf.freebsd.org:/var/tmp/deviant3/sys/amd64/compile/PHO\
21
22[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
23
24. ../default.cfg
25set -u
26prog=$(basename "$0" .sh)
27cat > /tmp/$prog.c <<EOF
28// https://syzkaller.appspot.com/bug?id=e5807bfa71ca13538ae5c94e160b0c959a40750d
29// autogenerated by syzkaller (https://github.com/google/syzkaller)
30// syzbot+1967136cd02c22bc6f0d@syzkaller.appspotmail.com
31
32#define _GNU_SOURCE
33
34#include <pwd.h>
35#include <setjmp.h>
36#include <signal.h>
37#include <stdarg.h>
38#include <stdbool.h>
39#include <stdint.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <sys/endian.h>
44#include <sys/syscall.h>
45#include <unistd.h>
46
47static __thread int clone_ongoing;
48static __thread int skip_segv;
49static __thread jmp_buf segv_env;
50
51static void segv_handler(int sig, siginfo_t* info, void* ctx __unused)
52{
53  if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) {
54    exit(sig);
55  }
56  uintptr_t addr = (uintptr_t)info->si_addr;
57  const uintptr_t prog_start = 1 << 20;
58  const uintptr_t prog_end = 100 << 20;
59  int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0;
60  int valid = addr < prog_start || addr > prog_end;
61  if (sig == SIGBUS)
62    valid = 1;
63  if (skip && valid) {
64    _longjmp(segv_env, 1);
65  }
66  exit(sig);
67}
68
69static void install_segv_handler(void)
70{
71  struct sigaction sa;
72  memset(&sa, 0, sizeof(sa));
73  sa.sa_sigaction = segv_handler;
74  sa.sa_flags = SA_NODEFER | SA_SIGINFO;
75  sigaction(SIGSEGV, &sa, NULL);
76  sigaction(SIGBUS, &sa, NULL);
77}
78
79#define NONFAILING(...)                                                        \
80  ({                                                                           \
81    int ok = 1;                                                                \
82    __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
83    if (_setjmp(segv_env) == 0) {                                              \
84      __VA_ARGS__;                                                             \
85    } else                                                                     \
86      ok = 0;                                                                  \
87    __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST);                       \
88    ok;                                                                        \
89  })
90
91uint64_t r[1] = {0xffffffffffffffff};
92
93int main(void)
94{
95  syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
96          /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
97          /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
98          /*fd=*/(intptr_t)-1, /*offset=*/0ul);
99  const char* reason;
100  (void)reason;
101  install_segv_handler();
102  intptr_t res = 0;
103  if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
104  }
105  //  openat\$crypto arguments: [
106  //    fd: const = 0xffffffffffffff9c (8 bytes)
107  //    file: ptr[in, buffer] {
108  //      buffer: {2f 64 65 76 2f 63 72 79 70 74 6f 00} (length 0xc)
109  //    }
110  //    flags: open_flags = 0x200 (8 bytes)
111  //    mode: const = 0x0 (8 bytes)
112  //  ]
113  //  returns fd_crypto
114  NONFAILING(memcpy((void*)0x200000000040, "/dev/crypto\000", 12));
115  res = syscall(SYS_openat, /*fd=*/0xffffffffffffff9cul,
116                /*file=*/0x200000000040ul, /*flags=O_CREAT*/ 0x200ul,
117                /*mode=*/0ul);
118  if (res != -1)
119    r[0] = res;
120  //  freebsd11_fstatfs arguments: [
121  //    fd: fd (resource)
122  //    buf: ptr[out, freebsd11_statfs] {
123  //      freebsd11_statfs {
124  //        version: int32 = 0x0 (4 bytes)
125  //        type: int32 = 0x0 (4 bytes)
126  //        flags: mount_flags = 0x0 (8 bytes)
127  //        bsize: int64 = 0x0 (8 bytes)
128  //        iosize: int64 = 0x0 (8 bytes)
129  //        blocks: int64 = 0x0 (8 bytes)
130  //        bfree: int64 = 0x0 (8 bytes)
131  //        bavail: int64 = 0x0 (8 bytes)
132  //        files: int64 = 0x0 (8 bytes)
133  //        ffree: int64 = 0x0 (8 bytes)
134  //        syncwrites: int64 = 0x0 (8 bytes)
135  //        asyncwrites: int64 = 0x0 (8 bytes)
136  //        syncreads: int64 = 0x0 (8 bytes)
137  //        asyncreads: int64 = 0x0 (8 bytes)
138  //        spare: array[int64] {
139  //          int64 = 0x0 (8 bytes)
140  //          int64 = 0x0 (8 bytes)
141  //          int64 = 0x0 (8 bytes)
142  //          int64 = 0x0 (8 bytes)
143  //          int64 = 0x0 (8 bytes)
144  //          int64 = 0x0 (8 bytes)
145  //          int64 = 0x0 (8 bytes)
146  //          int64 = 0x0 (8 bytes)
147  //          int64 = 0x0 (8 bytes)
148  //          int64 = 0x0 (8 bytes)
149  //        }
150  //        namemax: int32 = 0x0 (4 bytes)
151  //        owner: uid (resource)
152  //        fsid: fsid {
153  //          val: array[int32] {
154  //            int32 = 0x0 (4 bytes)
155  //            int32 = 0x0 (4 bytes)
156  //          }
157  //        }
158  //        cspare: buffer: (DirOut)
159  //        fstype: buffer: (DirOut)
160  //        mnton: buffer: (DirOut)
161  //        mntfrom: buffer: (DirOut)
162  //      }
163  //    }
164  //  ]
165  syscall(SYS_freebsd11_fstatfs, /*fd=*/r[0], /*buf=*/0x200000000080ul);
166  //  mprotect arguments: [
167  //    addr: VMA[0x4000]
168  //    len: len = 0x4000 (8 bytes)
169  //    prot: mmap_prot = 0x1 (8 bytes)
170  //  ]
171  syscall(SYS_mprotect, /*addr=*/0x200000000000ul, /*len=*/0x4000ul,
172          /*prot=PROT_READ*/ 1ul);
173  //  unmount arguments: [
174  //    path: ptr[in, buffer] {
175  //      buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8)
176  //    }
177  //    flags: mount_flags = 0xc40006c8 (8 bytes)
178  //  ]
179  NONFAILING(memcpy((void*)0x200000000200, "./file1\000", 8));
180  syscall(
181      SYS_unmount, /*path=*/0x200000000200ul,
182      /*flags=MNT_EXPORTANON|MNT_DEFEXPORTED|MNT_EXRDONLY|MNT_MULTILABEL|MNT_NOCLUSTERW|MNT_NOCLUSTERR|MNT_ASYNC|0x8*/
183      0xc40006c8ul);
184  return 0;
185}
186EOF
187mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
188
189(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) &
190sleep 5
191
192kldstat | grep -q cryptodev && loaded=0 || { kldload cryptodev.ko && loaded=1; }
193work=/tmp/$prog.dir
194rm -rf $work
195mkdir $work
196cd /tmp/$prog.dir
197for i in `jot 30`; do
198	(
199		mkdir d$i
200		cd d$i
201		timeout 3m /tmp/$prog > /dev/null 2>&1 &
202	)
203done
204while pgrep -q $prog; do sleep 2; done
205while pkill swap; do :; done
206wait
207
208rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core $work
209[ $loaded -eq 1 ] && kldunload cryptodev.ko
210exit 0
211