1#!/bin/sh 2 3# panic: vm_pager_assert_in: page 0xfffffe001987bcc0 is mapped 4# cpuid = 10 5# time = 1745335200 6# KDB: stack backtrace: 7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0108807700 8# vpanic() at vpanic+0x136/frame 0xfffffe0108807830 9# panic() at panic+0x43/frame 0xfffffe0108807890 10# vm_pager_assert_in() at vm_pager_assert_in+0x1fa/frame 0xfffffe01088078d0 11# vm_pager_get_pages() at vm_pager_get_pages+0x3d/frame 0xfffffe0108807920 12# vm_fault_getpages() at vm_fault_getpages+0x22b/frame 0xfffffe0108807980 13# vm_fault_object() at vm_fault_object+0x2ab/frame 0xfffffe01088079e0 14# vm_fault() at vm_fault+0x2d1/frame 0xfffffe0108807b40 15# vm_map_wire_locked() at vm_map_wire_locked+0x385/frame 0xfffffe0108807bf0 16# vm_mmap_object() at vm_mmap_object+0x2fd/frame 0xfffffe0108807c50 17# vn_mmap() at vn_mmap+0x152/frame 0xfffffe0108807ce0 18# kern_mmap() at kern_mmap+0x621/frame 0xfffffe0108807dc0 19# sys_mmap() at sys_mmap+0x42/frame 0xfffffe0108807e00 20# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe0108807f30 21# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0108807f30 22# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x82438d7fa, rsp = 0x824847f68, rbp = 0x824847f90 --- 23# KDB: enter: panic 24# [ thread pid 43067 tid 146060 ] 25# Stopped at kdb_enter+0x33: movq $0,0x124d7e2(%rip) 26# db> x/s version 27# version: FreeBSD 15.0-CURRENT #2 main-n276647-a098111a28ed-dirty: Tue Apr 22 16:37:39 CEST 2025 28# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO 29# db> 30 31[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 32 33. ../default.cfg 34set -u 35prog=$(basename "$0" .sh) 36cat > /tmp/$prog.c <<EOF 37// https://syzkaller.appspot.com/bug?id=bab5b2c0d3e8f95d52a06ab501ddb3c11200a5c9 38// autogenerated by syzkaller (https://github.com/google/syzkaller) 39// syzbot+1cc9ede76727d2ea2e8d@syzkaller.appspotmail.com 40 41#define _GNU_SOURCE 42 43#include <sys/types.h> 44 45#include <errno.h> 46#include <pthread.h> 47#include <pwd.h> 48#include <signal.h> 49#include <stdarg.h> 50#include <stdbool.h> 51#include <stdint.h> 52#include <stdio.h> 53#include <stdlib.h> 54#include <string.h> 55#include <sys/endian.h> 56#include <sys/syscall.h> 57#include <sys/wait.h> 58#include <time.h> 59#include <unistd.h> 60 61static void kill_and_wait(int pid, int* status) 62{ 63 kill(pid, SIGKILL); 64 while (waitpid(-1, status, 0) != pid) { 65 } 66} 67 68static void sleep_ms(uint64_t ms) 69{ 70 usleep(ms * 1000); 71} 72 73static uint64_t current_time_ms(void) 74{ 75 struct timespec ts; 76 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 77 exit(1); 78 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 79} 80 81static void thread_start(void* (*fn)(void*), void* arg) 82{ 83 pthread_t th; 84 pthread_attr_t attr; 85 pthread_attr_init(&attr); 86 pthread_attr_setstacksize(&attr, 128 << 10); 87 int i = 0; 88 for (; i < 100; i++) { 89 if (pthread_create(&th, &attr, fn, arg) == 0) { 90 pthread_attr_destroy(&attr); 91 return; 92 } 93 if (errno == EAGAIN) { 94 usleep(50); 95 continue; 96 } 97 break; 98 } 99 exit(1); 100} 101 102typedef struct { 103 pthread_mutex_t mu; 104 pthread_cond_t cv; 105 int state; 106} event_t; 107 108static void event_init(event_t* ev) 109{ 110 if (pthread_mutex_init(&ev->mu, 0)) 111 exit(1); 112 if (pthread_cond_init(&ev->cv, 0)) 113 exit(1); 114 ev->state = 0; 115} 116 117static void event_reset(event_t* ev) 118{ 119 ev->state = 0; 120} 121 122static void event_set(event_t* ev) 123{ 124 pthread_mutex_lock(&ev->mu); 125 if (ev->state) 126 exit(1); 127 ev->state = 1; 128 pthread_mutex_unlock(&ev->mu); 129 pthread_cond_broadcast(&ev->cv); 130} 131 132static void event_wait(event_t* ev) 133{ 134 pthread_mutex_lock(&ev->mu); 135 while (!ev->state) 136 pthread_cond_wait(&ev->cv, &ev->mu); 137 pthread_mutex_unlock(&ev->mu); 138} 139 140static int event_isset(event_t* ev) 141{ 142 pthread_mutex_lock(&ev->mu); 143 int res = ev->state; 144 pthread_mutex_unlock(&ev->mu); 145 return res; 146} 147 148static int event_timedwait(event_t* ev, uint64_t timeout) 149{ 150 uint64_t start = current_time_ms(); 151 uint64_t now = start; 152 pthread_mutex_lock(&ev->mu); 153 for (;;) { 154 if (ev->state) 155 break; 156 uint64_t remain = timeout - (now - start); 157 struct timespec ts; 158 ts.tv_sec = remain / 1000; 159 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 160 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 161 now = current_time_ms(); 162 if (now - start > timeout) 163 break; 164 } 165 int res = ev->state; 166 pthread_mutex_unlock(&ev->mu); 167 return res; 168} 169 170struct thread_t { 171 int created, call; 172 event_t ready, done; 173}; 174 175static struct thread_t threads[16]; 176static void execute_call(int call); 177static int running; 178 179static void* thr(void* arg) 180{ 181 struct thread_t* th = (struct thread_t*)arg; 182 for (;;) { 183 event_wait(&th->ready); 184 event_reset(&th->ready); 185 execute_call(th->call); 186 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 187 event_set(&th->done); 188 } 189 return 0; 190} 191 192static void execute_one(void) 193{ 194 if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { 195 } 196 int i, call, thread; 197 for (call = 0; call < 11; call++) { 198 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 199 thread++) { 200 struct thread_t* th = &threads[thread]; 201 if (!th->created) { 202 th->created = 1; 203 event_init(&th->ready); 204 event_init(&th->done); 205 event_set(&th->done); 206 thread_start(thr, th); 207 } 208 if (!event_isset(&th->done)) 209 continue; 210 event_reset(&th->done); 211 th->call = call; 212 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 213 event_set(&th->ready); 214 event_timedwait(&th->done, 50); 215 break; 216 } 217 } 218 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 219 sleep_ms(1); 220} 221 222static void execute_one(void); 223 224#define WAIT_FLAGS 0 225 226static void loop(void) 227{ 228// int iter = 0; 229 for (;; /*iter++*/) { 230 int pid = fork(); 231 if (pid < 0) 232 exit(1); 233 if (pid == 0) { 234 execute_one(); 235 exit(0); 236 } 237 int status = 0; 238 uint64_t start = current_time_ms(); 239 for (;;) { 240 sleep_ms(10); 241 if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 242 break; 243 if (current_time_ms() - start < 5000) 244 continue; 245 kill_and_wait(pid, &status); 246 break; 247 } 248 } 249} 250 251uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 252 0xffffffffffffffff}; 253 254void execute_call(int call) 255{ 256 intptr_t res = 0; 257 switch (call) { 258 case 0: 259 memcpy((void*)0x200000000200, "./file0\000", 8); 260 res = syscall(SYS_openat, /*fd=*/0xffffff9c, /*file=*/0x200000000200ul, 261 /*flags=O_VERIFY|O_CREAT|O_CLOEXEC|O_WRONLY*/ 0x300201ul, 262 /*mode=S_IWGRP|S_IXUSR|S_IWUSR*/ 0xd0ul); 263 if (res != -1) 264 r[0] = res; 265 break; 266 case 1: 267 *(uint32_t*)0x200000000240 = r[0]; 268 *(uint64_t*)0x200000000248 = 0x80000002; 269 *(uint64_t*)0x200000000250 = 0x200000000080; 270 memcpy((void*)0x200000000080, "\x1f\x9a\xc4", 3); 271 *(uint64_t*)0x200000000258 = 3; 272 *(uint32_t*)0x200000000260 = 0; 273 *(uint32_t*)0x200000000264 = 0; 274 *(uint64_t*)0x200000000268 = 0; 275 *(uint32_t*)0x200000000270 = 0; 276 *(uint32_t*)0x200000000274 = 0; 277 *(uint64_t*)0x200000000278 = 0; 278 *(uint64_t*)0x200000000280 = 7; 279 *(uint64_t*)0x200000000288 = 0; 280 *(uint32_t*)0x200000000290 = 0; 281 *(uint32_t*)0x200000000294 = 0; 282 *(uint64_t*)0x200000000298 = 0; 283 *(uint64_t*)0x2000000002a0 = 0; 284 *(uint64_t*)0x2000000002a8 = 0; 285 syscall(SYS_aio_write, /*iocb=*/0x200000000240ul); 286 break; 287 case 2: 288 syscall(SYS_mlockall, /*flags=MCL_FUTURE*/ 2ul); 289 break; 290 case 3: 291 memcpy((void*)0x200000000100, "./file0\000", 8); 292 res = syscall(SYS_open, /*file=*/0x200000000100ul, 293 /*flags=O_DIRECT*/ 0x10000ul, /*mode=*/0ul); 294 if (res != -1) 295 r[1] = res; 296 break; 297 case 4: 298 *(uint64_t*)0x200000001780 = 0x200000000180; 299 *(uint64_t*)0x200000001788 = 0x1b133353141e377d; 300 syscall(SYS_preadv, /*fd=*/r[1], /*vec=*/0x200000001780ul, 301 /*vlen=*/0x10000000000000d1ul, /*off=*/0ul); 302 break; 303 case 5: 304 memcpy((void*)0x200000000040, "./file0\000", 8); 305 syscall( 306 SYS_open, /*file=*/0x200000000040ul, 307 /*flags=O_TRUNC|O_NONBLOCK|O_NOFOLLOW|O_CREAT|O_APPEND|0x2*/ 0x70eul, 308 /*mode=*/0ul); 309 break; 310 case 6: 311 memcpy((void*)0x200000000480, "./file0\000", 8); 312 res = syscall( 313 SYS_open, /*file=*/0x200000000480ul, 314 /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80400000000000*/ 0x80400000000206ul, 315 /*mode=*/0ul); 316 if (res != -1) 317 r[2] = res; 318 break; 319 case 7: 320 syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x200000ul, 321 /*prot=PROT_WRITE|PROT_READ*/ 3ul, 322 /*flags=MAP_FIXED|MAP_SHARED|0x20000*/ 0x20011ul, /*fd=*/r[2], 323 /*offset=*/0ul); 324 break; 325 case 8: 326 memcpy((void*)0x200000000040, "./file0\000", 8); 327 syscall(SYS_truncate, /*file=*/0x200000000040ul, /*len=*/0xaa480ul); 328 break; 329 case 9: 330 memcpy((void*)0x200000000480, "./file0\000", 8); 331 res = syscall(SYS_open, /*file=*/0x200000000480ul, /*flags=*/0ul, 332 /*mode=*/0ul); 333 if (res != -1) 334 r[3] = res; 335 break; 336 case 10: 337 syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x200000ul, 338 /*prot=PROT_WRITE|PROT_READ*/ 3ul, 339 /*flags=MAP_FIXED|MAP_PRIVATE*/ 0x12ul, /*fd=*/r[3], 340 /*offset=*/0ul); 341 break; 342 } 343} 344int main(void) 345{ 346 syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, 347 /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, 348 /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, 349 /*fd=*/(intptr_t)-1, /*offset=*/0ul); 350 const char* reason; 351 (void)reason; 352 loop(); 353 return 0; 354} 355EOF 356mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1 357 358(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) & 359sleep 5 360 361work=/tmp/$prog.dir 362rm -rf $work 363mkdir $work 364cd /tmp/$prog.dir 365for i in `jot 30`; do 366 ( 367 mkdir d$i 368 cd d$i 369 timeout 3m /tmp/$prog > /dev/null 2>&1 & 370 ) 371done 372while pgrep -q $prog; do sleep 2; done 373while pkill swap; do :; done 374wait 375 376rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work 377exit 0 378