1#!/bin/sh 2 3# panic: sofree:1883 curvnet is NULL, so=0xfffff8017ca59000 4# cpuid = 8 5# time = 1746559098 6# KDB: stack backtrace: 7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0182b5c8d0 8# vpanic() at vpanic+0x136/frame 0xfffffe0182b5ca00 9# panic() at panic+0x43/frame 0xfffffe0182b5ca60 10# sorele_locked() at sorele_locked+0x25f/frame 0xfffffe0182b5ca90 11# uipc_sendfile_wait() at uipc_sendfile_wait+0x1df/frame 0xfffffe0182b5caf0 12# vn_sendfile() at vn_sendfile+0x59b/frame 0xfffffe0182b5cd70 13# sendfile() at sendfile+0x129/frame 0xfffffe0182b5ce00 14# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe0182b5cf30 15# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0182b5cf30 16# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x8223fb72a, rsp = 0x824baaf58, rbp = 0x824baaf90 --- 17# KDB: enter: panic 18# [ thread pid 6382 tid 103296 ] 19# Stopped at kdb_enter+0x33: movq $0,0x122f202(%rip) 20# db> x/s version 21# version: FreeBSD 15.0-CURRENT #0 main-n277057-794e792121ba-dirty: Tue May 6 18:34:20 CEST 2025 22# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO 23# db> 24 25[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 26 27. ../default.cfg 28set -u 29prog=$(basename "$0" .sh) 30cat > /tmp/$prog.c <<EOF 31// https://syzkaller.appspot.com/bug?id=f04b36c4f2b84533225a1bd695a0aed2efa559e5 32// autogenerated by syzkaller (https://github.com/google/syzkaller) 33// syzbot+7b0b20cf2c672c181d98@syzkaller.appspotmail.com 34 35#define _GNU_SOURCE 36 37#include <errno.h> 38#include <pthread.h> 39#include <pwd.h> 40#include <stdarg.h> 41#include <stdbool.h> 42#include <stdint.h> 43#include <stdio.h> 44#include <stdlib.h> 45#include <string.h> 46#include <sys/endian.h> 47#include <sys/syscall.h> 48#include <time.h> 49#include <unistd.h> 50 51static void sleep_ms(uint64_t ms) 52{ 53 usleep(ms * 1000); 54} 55 56static uint64_t current_time_ms(void) 57{ 58 struct timespec ts; 59 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 60 exit(1); 61 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 62} 63 64static void thread_start(void* (*fn)(void*), void* arg) 65{ 66 pthread_t th; 67 pthread_attr_t attr; 68 pthread_attr_init(&attr); 69 pthread_attr_setstacksize(&attr, 128 << 10); 70 int i = 0; 71 for (; i < 100; i++) { 72 if (pthread_create(&th, &attr, fn, arg) == 0) { 73 pthread_attr_destroy(&attr); 74 return; 75 } 76 if (errno == EAGAIN) { 77 usleep(50); 78 continue; 79 } 80 break; 81 } 82 exit(1); 83} 84 85typedef struct { 86 pthread_mutex_t mu; 87 pthread_cond_t cv; 88 int state; 89} event_t; 90 91static void event_init(event_t* ev) 92{ 93 if (pthread_mutex_init(&ev->mu, 0)) 94 exit(1); 95 if (pthread_cond_init(&ev->cv, 0)) 96 exit(1); 97 ev->state = 0; 98} 99 100static void event_reset(event_t* ev) 101{ 102 ev->state = 0; 103} 104 105static void event_set(event_t* ev) 106{ 107 pthread_mutex_lock(&ev->mu); 108 if (ev->state) 109 exit(1); 110 ev->state = 1; 111 pthread_mutex_unlock(&ev->mu); 112 pthread_cond_broadcast(&ev->cv); 113} 114 115static void event_wait(event_t* ev) 116{ 117 pthread_mutex_lock(&ev->mu); 118 while (!ev->state) 119 pthread_cond_wait(&ev->cv, &ev->mu); 120 pthread_mutex_unlock(&ev->mu); 121} 122 123static int event_isset(event_t* ev) 124{ 125 pthread_mutex_lock(&ev->mu); 126 int res = ev->state; 127 pthread_mutex_unlock(&ev->mu); 128 return res; 129} 130 131static int event_timedwait(event_t* ev, uint64_t timeout) 132{ 133 uint64_t start = current_time_ms(); 134 uint64_t now = start; 135 pthread_mutex_lock(&ev->mu); 136 for (;;) { 137 if (ev->state) 138 break; 139 uint64_t remain = timeout - (now - start); 140 struct timespec ts; 141 ts.tv_sec = remain / 1000; 142 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 143 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 144 now = current_time_ms(); 145 if (now - start > timeout) 146 break; 147 } 148 int res = ev->state; 149 pthread_mutex_unlock(&ev->mu); 150 return res; 151} 152 153struct thread_t { 154 int created, call; 155 event_t ready, done; 156}; 157 158static struct thread_t threads[16]; 159static void execute_call(int call); 160static int running; 161 162static void* thr(void* arg) 163{ 164 struct thread_t* th = (struct thread_t*)arg; 165 for (;;) { 166 event_wait(&th->ready); 167 event_reset(&th->ready); 168 execute_call(th->call); 169 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 170 event_set(&th->done); 171 } 172 return 0; 173} 174 175static void loop(void) 176{ 177 if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { 178 } 179 int i, call, thread; 180 for (call = 0; call < 8; call++) { 181 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 182 thread++) { 183 struct thread_t* th = &threads[thread]; 184 if (!th->created) { 185 th->created = 1; 186 event_init(&th->ready); 187 event_init(&th->done); 188 event_set(&th->done); 189 thread_start(thr, th); 190 } 191 if (!event_isset(&th->done)) 192 continue; 193 event_reset(&th->done); 194 th->call = call; 195 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 196 event_set(&th->ready); 197 event_timedwait(&th->done, 50); 198 break; 199 } 200 } 201 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 202 sleep_ms(1); 203} 204 205uint64_t r[5] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 206 0xffffffffffffffff, 0xffffffffffffffff}; 207 208void execute_call(int call) 209{ 210 intptr_t res = 0; 211 switch (call) { 212 case 0: 213 memcpy((void*)0x200000000480, "./file0\000", 8); 214 res = syscall( 215 SYS_open, /*file=*/0x200000000480ul, 216 /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80000000000000*/ 0x80000000000206ul, 217 /*mode=*/0ul); 218 if (res != -1) 219 r[0] = res; 220 break; 221 case 1: 222 syscall(SYS_ftruncate, /*fd=*/r[0], /*len=*/0x3862ul); 223 break; 224 case 2: 225 res = syscall(SYS_socket, /*domain=*/2ul, /*type=*/2ul, /*proto=*/0x88); 226 if (res != -1) 227 r[1] = res; 228 break; 229 case 3: 230 res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul, 231 /*proto=*/0, /*fds=*/0x200000000180ul); 232 if (res != -1) { 233 r[2] = *(uint32_t*)0x200000000180; 234 r[3] = *(uint32_t*)0x200000000184; 235 } 236 break; 237 case 4: 238 syscall(SYS_dup2, /*oldfd=*/r[2], /*newfd=*/r[1]); 239 break; 240 case 5: 241 memcpy((void*)0x200000000140, "./file0\000", 8); 242 res = syscall(SYS_open, /*file=*/0x200000000140ul, /*flags=*/0ul, 243 /*mode=*/0ul); 244 if (res != -1) 245 r[4] = res; 246 break; 247 case 6: 248 syscall(SYS_sendfile, /*fd=*/r[4], /*s=*/r[1], /*offset=*/0ul, 249 /*nbytes=*/0ul, /*hdtr=*/0ul, /*sbytes=*/0ul, 250 /*flags=SF_SYNC|SF_NOCACHE*/ 0x14ul); 251 break; 252 case 7: 253 syscall(SYS_dup2, /*oldfd=*/r[4], /*newfd=*/r[3]); 254 break; 255 } 256} 257int main(void) 258{ 259 syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, 260 /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, 261 /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, 262 /*fd=*/(intptr_t)-1, /*offset=*/0ul); 263 const char* reason; 264 (void)reason; 265 loop(); 266 return 0; 267} 268EOF 269mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1 270 271(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) & 272sleep 5 273 274work=/tmp/$prog.dir 275rm -rf $work 276mkdir $work 277cd /tmp/$prog.dir 278for i in `jot 30`; do 279 ( 280 mkdir d$i 281 cd d$i 282 timeout 3m /tmp/$prog > /dev/null 2>&1 & 283 ) 284done 285while pgrep -q $prog; do sleep 2; done 286while pkill swap; do :; done 287wait 288 289rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work 290exit 0 291