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