1*8a272653SPeter Holm#!/bin/sh 2*8a272653SPeter Holm 3*8a272653SPeter Holm# Kernel page fault with the following non-sleepable locks held: 4*8a272653SPeter Holm# exclusive sleep mutex so_rcv (so_rcv) r = 0 (0xfffffe012b5ee300) locked @ kern/uipc_usrreq.c:1272 5*8a272653SPeter Holm# exclusive sleep mutex socket (socket) r = 0 (0xfffffe012b5ee1a8) locked @ kern/uipc_usrreq.c:1265 6*8a272653SPeter Holm# shared rw unp_link_rwlock (unp_link_rwlock) r = 0 (0xffffffff81d99640) locked @ kern/uipc_usrreq.c:1334 7*8a272653SPeter Holm# stack backtrace: 8*8a272653SPeter Holm# #0 0xffffffff80c35701 at witness_debugger+0x71 9*8a272653SPeter Holm# #1 0xffffffff80c3669d at witness_warn+0x40d 10*8a272653SPeter Holm# #2 0xffffffff8106fb90 at trap_pfault+0x80 11*8a272653SPeter Holm# #3 0xffffffff8106f1a5 at trap+0x2a5 12*8a272653SPeter Holm# #4 0xffffffff810450d8 at calltrap+0x8 13*8a272653SPeter Holm# #5 0xffffffff80bc6fcc at sendfile_iodone+0x1ac 14*8a272653SPeter Holm# #6 0xffffffff80f3d98a at vnode_pager_generic_getpages_done_async+0x3a 15*8a272653SPeter Holm# #7 0xffffffff80c8236c at bufdone+0x6c 16*8a272653SPeter Holm# #8 0xffffffff80b0c06e at g_io_deliver+0x25e 17*8a272653SPeter Holm# #9 0xffffffff80b0c06e at g_io_deliver+0x25e 18*8a272653SPeter Holm# #10 0xffffffff80b08dfd at g_disk_done+0xed 19*8a272653SPeter Holm# #11 0xffffffff803ac1f3 at dadone+0x603 20*8a272653SPeter Holm# #12 0xffffffff8037ddf2 at xpt_done_process+0x382 21*8a272653SPeter Holm# #13 0xffffffff8037fdb5 at xpt_done_td+0xf5 22*8a272653SPeter Holm# #14 0xffffffff80b85b10 at fork_exit+0x80 23*8a272653SPeter Holm# #15 0xffffffff8104611e at fork_trampoline+0xe 24*8a272653SPeter Holm# 25*8a272653SPeter Holm# 26*8a272653SPeter Holm# Fatal trap 12: page fault while in kernel mode 27*8a272653SPeter Holm# cpuid = 23; apic id = 2b 28*8a272653SPeter Holm# fault virtual address = 0x8 29*8a272653SPeter Holm# fault code = supervisor read data, page not present 30*8a272653SPeter Holm# instruction pointer = 0x20:0xffffffff80c74bc0 31*8a272653SPeter Holm# stack pointer = 0x0:0xfffffe0126b118e0 32*8a272653SPeter Holm# frame pointer = 0x0:0xfffffe0126b11920 33*8a272653SPeter Holm# code segment = base 0x0, limit 0xfffff, type 0x1b 34*8a272653SPeter Holm# = DPL 0, pres 1, long 1, def32 0, gran 1 35*8a272653SPeter Holm# processor eflags = interrupt enabled, resume, IOPL = 0 36*8a272653SPeter Holm# current process = 32 (doneq0) 37*8a272653SPeter Holm# trap number = 12 38*8a272653SPeter Holm# panic: page fault 39*8a272653SPeter Holm# cpuid = 23 40*8a272653SPeter Holm# time = 1591531029 41*8a272653SPeter Holm# KDB: stack backtrace: 42*8a272653SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0126b11590 43*8a272653SPeter Holm# vpanic() at vpanic+0x182/frame 0xfffffe0126b115e0 44*8a272653SPeter Holm# panic() at panic+0x43/frame 0xfffffe0126b11640 45*8a272653SPeter Holm# trap_fatal() at trap_fatal+0x387/frame 0xfffffe0126b116a0 46*8a272653SPeter Holm# trap_pfault() at trap_pfault+0x99/frame 0xfffffe0126b11700 47*8a272653SPeter Holm# trap() at trap+0x2a5/frame 0xfffffe0126b11810 48*8a272653SPeter Holm# calltrap() at calltrap+0x8/frame 0xfffffe0126b11810 49*8a272653SPeter Holm# --- trap 0xc, rip = 0xffffffff80c74bc0, rsp = 0xfffffe0126b118e0, rbp = 0xfffffe0126b11920 --- 50*8a272653SPeter Holm# uipc_ready() at uipc_ready+0x1f0/frame 0xfffffe0126b11920 51*8a272653SPeter Holm# sendfile_iodone() at sendfile_iodone+0x1ac/frame 0xfffffe0126b11960 52*8a272653SPeter Holm# vnode_pager_generic_getpages_done_async() at vnode_pager_generic_getpages_done_async+0x3a/frame 0xfffffe0126b11980 53*8a272653SPeter Holm# bufdone() at bufdone+0x6c/frame 0xfffffe0126b119f0 54*8a272653SPeter Holm# g_io_deliver() at g_io_deliver+0x25e/frame 0xfffffe0126b11a40 55*8a272653SPeter Holm# g_io_deliver() at g_io_deliver+0x25e/frame 0xfffffe0126b11a90 56*8a272653SPeter Holm# g_disk_done() at g_disk_done+0xed/frame 0xfffffe0126b11ad0 57*8a272653SPeter Holm# dadone() at dadone+0x603/frame 0xfffffe0126b11b20 58*8a272653SPeter Holm# xpt_done_process() at xpt_done_process+0x382/frame 0xfffffe0126b11b60 59*8a272653SPeter Holm# xpt_done_td() at xpt_done_td+0xf5/frame 0xfffffe0126b11bb0 60*8a272653SPeter Holm# fork_exit() at fork_exit+0x80/frame 0xfffffe0126b11bf0 61*8a272653SPeter Holm# fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe0126b11bf0 62*8a272653SPeter Holm# --- trap 0, rip = 0, rsp = 0, rbp = 0 --- 63*8a272653SPeter Holm# KDB: enter: panic 64*8a272653SPeter Holm# [ thread pid 32 tid 100163 ] 65*8a272653SPeter Holm# Stopped at kdb_enter+0x37: movq $0,0x10c72c6(%rip) 66*8a272653SPeter Holm# db> 67*8a272653SPeter Holm 68*8a272653SPeter Holm# Reproduced on r361889 69*8a272653SPeter Holm# Fixed by r363682 70*8a272653SPeter Holm 71*8a272653SPeter Holm[ `uname -p` = "i386" ] && exit 0 72*8a272653SPeter Holm 73*8a272653SPeter Holm. ../default.cfg 74*8a272653SPeter Holmcat > /tmp/syzkaller13.c <<EOF 75*8a272653SPeter Holm// https://syzkaller.appspot.com/bug?id=8a63fce7c52d85d6fca9aca543ce5a77cdd15f25 76*8a272653SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller) 77*8a272653SPeter Holm// Reported-by: syzbot+6a689cc9c27bd265237a@syzkaller.appspotmail.com 78*8a272653SPeter Holm 79*8a272653SPeter Holm#define _GNU_SOURCE 80*8a272653SPeter Holm 81*8a272653SPeter Holm#include <sys/types.h> 82*8a272653SPeter Holm 83*8a272653SPeter Holm#include <dirent.h> 84*8a272653SPeter Holm#include <pwd.h> 85*8a272653SPeter Holm#include <signal.h> 86*8a272653SPeter Holm#include <stdarg.h> 87*8a272653SPeter Holm#include <stdbool.h> 88*8a272653SPeter Holm#include <stdint.h> 89*8a272653SPeter Holm#include <stdio.h> 90*8a272653SPeter Holm#include <stdlib.h> 91*8a272653SPeter Holm#include <string.h> 92*8a272653SPeter Holm#include <sys/endian.h> 93*8a272653SPeter Holm#include <sys/stat.h> 94*8a272653SPeter Holm#include <sys/syscall.h> 95*8a272653SPeter Holm#include <sys/wait.h> 96*8a272653SPeter Holm#include <time.h> 97*8a272653SPeter Holm#include <unistd.h> 98*8a272653SPeter Holm 99*8a272653SPeter Holmstatic unsigned long long procid; 100*8a272653SPeter Holm 101*8a272653SPeter Holmstatic void kill_and_wait(int pid, int* status) 102*8a272653SPeter Holm{ 103*8a272653SPeter Holm kill(pid, SIGKILL); 104*8a272653SPeter Holm while (waitpid(-1, status, 0) != pid) { 105*8a272653SPeter Holm } 106*8a272653SPeter Holm} 107*8a272653SPeter Holm 108*8a272653SPeter Holmstatic void sleep_ms(uint64_t ms) 109*8a272653SPeter Holm{ 110*8a272653SPeter Holm usleep(ms * 1000); 111*8a272653SPeter Holm} 112*8a272653SPeter Holm 113*8a272653SPeter Holmstatic uint64_t current_time_ms(void) 114*8a272653SPeter Holm{ 115*8a272653SPeter Holm struct timespec ts; 116*8a272653SPeter Holm if (clock_gettime(CLOCK_MONOTONIC, &ts)) 117*8a272653SPeter Holm exit(1); 118*8a272653SPeter Holm return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 119*8a272653SPeter Holm} 120*8a272653SPeter Holm 121*8a272653SPeter Holmstatic void use_temporary_dir(void) 122*8a272653SPeter Holm{ 123*8a272653SPeter Holm char tmpdir_template[] = "./syzkaller.XXXXXX"; 124*8a272653SPeter Holm char* tmpdir = mkdtemp(tmpdir_template); 125*8a272653SPeter Holm if (!tmpdir) 126*8a272653SPeter Holm exit(1); 127*8a272653SPeter Holm if (chmod(tmpdir, 0777)) 128*8a272653SPeter Holm exit(1); 129*8a272653SPeter Holm if (chdir(tmpdir)) 130*8a272653SPeter Holm exit(1); 131*8a272653SPeter Holm} 132*8a272653SPeter Holm 133*8a272653SPeter Holmstatic void remove_dir(const char* dir) 134*8a272653SPeter Holm{ 135*8a272653SPeter Holm DIR* dp; 136*8a272653SPeter Holm struct dirent* ep; 137*8a272653SPeter Holm dp = opendir(dir); 138*8a272653SPeter Holm if (dp == NULL) 139*8a272653SPeter Holm exit(1); 140*8a272653SPeter Holm while ((ep = readdir(dp))) { 141*8a272653SPeter Holm if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) 142*8a272653SPeter Holm continue; 143*8a272653SPeter Holm char filename[FILENAME_MAX]; 144*8a272653SPeter Holm snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name); 145*8a272653SPeter Holm struct stat st; 146*8a272653SPeter Holm if (lstat(filename, &st)) 147*8a272653SPeter Holm exit(1); 148*8a272653SPeter Holm if (S_ISDIR(st.st_mode)) { 149*8a272653SPeter Holm remove_dir(filename); 150*8a272653SPeter Holm continue; 151*8a272653SPeter Holm } 152*8a272653SPeter Holm if (unlink(filename)) 153*8a272653SPeter Holm exit(1); 154*8a272653SPeter Holm } 155*8a272653SPeter Holm closedir(dp); 156*8a272653SPeter Holm if (rmdir(dir)) 157*8a272653SPeter Holm exit(1); 158*8a272653SPeter Holm} 159*8a272653SPeter Holm 160*8a272653SPeter Holmstatic void execute_one(void); 161*8a272653SPeter Holm 162*8a272653SPeter Holm#define WAIT_FLAGS 0 163*8a272653SPeter Holm 164*8a272653SPeter Holmstatic void loop(void) 165*8a272653SPeter Holm{ 166*8a272653SPeter Holm int iter; 167*8a272653SPeter Holm for (iter = 0;; iter++) { 168*8a272653SPeter Holm char cwdbuf[32]; 169*8a272653SPeter Holm sprintf(cwdbuf, "./%d", iter); 170*8a272653SPeter Holm if (mkdir(cwdbuf, 0777)) 171*8a272653SPeter Holm exit(1); 172*8a272653SPeter Holm int pid = fork(); 173*8a272653SPeter Holm if (pid < 0) 174*8a272653SPeter Holm exit(1); 175*8a272653SPeter Holm if (pid == 0) { 176*8a272653SPeter Holm if (chdir(cwdbuf)) 177*8a272653SPeter Holm exit(1); 178*8a272653SPeter Holm execute_one(); 179*8a272653SPeter Holm exit(0); 180*8a272653SPeter Holm } 181*8a272653SPeter Holm int status = 0; 182*8a272653SPeter Holm uint64_t start = current_time_ms(); 183*8a272653SPeter Holm for (;;) { 184*8a272653SPeter Holm if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 185*8a272653SPeter Holm break; 186*8a272653SPeter Holm sleep_ms(1); 187*8a272653SPeter Holm if (current_time_ms() - start < 5 * 1000) 188*8a272653SPeter Holm continue; 189*8a272653SPeter Holm kill_and_wait(pid, &status); 190*8a272653SPeter Holm break; 191*8a272653SPeter Holm } 192*8a272653SPeter Holm remove_dir(cwdbuf); 193*8a272653SPeter Holm } 194*8a272653SPeter Holm} 195*8a272653SPeter Holm 196*8a272653SPeter Holmuint64_t r[5] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 197*8a272653SPeter Holm 0xffffffffffffffff, 0xffffffffffffffff}; 198*8a272653SPeter Holm 199*8a272653SPeter Holmvoid execute_one(void) 200*8a272653SPeter Holm{ 201*8a272653SPeter Holm intptr_t res = 0; 202*8a272653SPeter Holm memcpy((void*)0x20000100, "./file0\000", 8); 203*8a272653SPeter Holm res = syscall(SYS_open, 0x20000100ul, 0x40000400000002c2ul, 0ul); 204*8a272653SPeter Holm if (res != -1) 205*8a272653SPeter Holm r[0] = res; 206*8a272653SPeter Holm syscall(SYS_fcntl, r[0], 4ul, 0x10048ul); 207*8a272653SPeter Holm *(uint64_t*)0x20000340 = 0x20000180; 208*8a272653SPeter Holm *(uint64_t*)0x20000348 = 0x81700; 209*8a272653SPeter Holm syscall(SYS_writev, r[0], 0x20000340ul, 0x1000000000000013ul); 210*8a272653SPeter Holm res = syscall(SYS_socket, 2ul, 2ul, 0x88); 211*8a272653SPeter Holm if (res != -1) 212*8a272653SPeter Holm r[1] = res; 213*8a272653SPeter Holm res = syscall(SYS_socketpair, 1ul, 1ul, 0, 0x20000000ul); 214*8a272653SPeter Holm if (res != -1) 215*8a272653SPeter Holm r[2] = *(uint32_t*)0x20000000; 216*8a272653SPeter Holm res = syscall(SYS_dup2, r[2], r[1]); 217*8a272653SPeter Holm if (res != -1) 218*8a272653SPeter Holm r[3] = res; 219*8a272653SPeter Holm memcpy((void*)0x20000140, "./file0\000", 8); 220*8a272653SPeter Holm res = syscall(SYS_open, 0x20000140ul, 0ul, 0ul); 221*8a272653SPeter Holm if (res != -1) 222*8a272653SPeter Holm r[4] = res; 223*8a272653SPeter Holm syscall(SYS_sendfile, r[4], r[3], 0ul, 1ul, 0ul, 0ul, 0ul); 224*8a272653SPeter Holm} 225*8a272653SPeter Holmint main(void) 226*8a272653SPeter Holm{ 227*8a272653SPeter Holm syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 228*8a272653SPeter Holm for (procid = 0; procid < 4; procid++) { 229*8a272653SPeter Holm if (fork() == 0) { 230*8a272653SPeter Holm use_temporary_dir(); 231*8a272653SPeter Holm loop(); 232*8a272653SPeter Holm } 233*8a272653SPeter Holm } 234*8a272653SPeter Holm sleep(1000000); 235*8a272653SPeter Holm return 0; 236*8a272653SPeter Holm} 237*8a272653SPeter HolmEOF 238*8a272653SPeter Holmmycc -o /tmp/syzkaller13 -Wall -Wextra -O2 /tmp/syzkaller13.c -lpthread || 239*8a272653SPeter Holm exit 1 240*8a272653SPeter Holm 241*8a272653SPeter Holm(cd ../testcases/swap; ./swap -t 1m -i 20 -h > /dev/null 2>&1) & 242*8a272653SPeter Holm(cd /tmp; ./syzkaller13) & 243*8a272653SPeter Holmsleep 60 244*8a272653SPeter Holmwhile pkill swap; do sleep .1; done 245*8a272653SPeter Holmpkill -9 syzkaller13 246*8a272653SPeter Holmwait 247*8a272653SPeter Holm 248*8a272653SPeter Holmrm -f /tmp/syzkaller13 /tmp/syzkaller13.* /tmp/file0 249*8a272653SPeter Holmexit 0 250