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