1#!/bin/sh 2 3# panic: ../../../kern/uipc_usrreq.c:1256: uipc_sosend_stream_or_seqpacket: Empty stailq 0xfffffe00ffe5fc88->stqh_last is 0xfffffe00ffe5fcd0, not head's first field address 4# cpuid = 5 5# time = 1749593630 6# KDB: stack backtrace: 7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00ffe5fab0 8# vpanic() at vpanic+0x136/frame 0xfffffe00ffe5fbe0 9# panic() at panic+0x43/frame 0xfffffe00ffe5fc40 10# uipc_sosend_stream_or_seqpacket() at uipc_sosend_stream_or_seqpacket+0xa39/frame 0xfffffe00ffe5fd10 11# sousrsend() at sousrsend+0x79/frame 0xfffffe00ffe5fd70 12# dofilewrite() at dofilewrite+0x81/frame 0xfffffe00ffe5fdc0 13# sys_writev() at sys_writev+0x69/frame 0xfffffe00ffe5fe00 14# amd64_syscall() at amd64_syscall+0x169/frame 0xfffffe00ffe5ff30 15# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe00ffe5ff30 16# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x82330181a, rsp = 0x8238dbf68, rbp = 0x8238dbf90 --- 17# KDB: enter: panic 18# [ thread pid 4484 tid 101524 ] 19# Stopped at kdb_enter+0x33: movq $0,0x122ebc2(%rip) 20# db> x/s version 21# version: FreeBSD 15.0-CURRENT #0 main-n277833-948078b65c27-dirty: Tue Jun 10 06:01:36 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=210ae0bfcef6324abfffbfaf10120b767106a990 32// autogenerated by syzkaller (https://github.com/google/syzkaller) 33// syzbot+cfcb8520b0071b548fba@syzkaller.appspotmail.com 34 35#define _GNU_SOURCE 36 37#include <sys/types.h> 38 39#include <errno.h> 40#include <pthread.h> 41#include <pwd.h> 42#include <signal.h> 43#include <stdarg.h> 44#include <stdbool.h> 45#include <stdint.h> 46#include <stdio.h> 47#include <stdlib.h> 48#include <string.h> 49#include <sys/endian.h> 50#include <sys/syscall.h> 51#include <sys/wait.h> 52#include <time.h> 53#include <unistd.h> 54 55static unsigned long long procid; 56 57static void kill_and_wait(int pid, int* status) 58{ 59 kill(pid, SIGKILL); 60 while (waitpid(-1, status, 0) != pid) { 61 } 62} 63 64static void sleep_ms(uint64_t ms) 65{ 66 usleep(ms * 1000); 67} 68 69static uint64_t current_time_ms(void) 70{ 71 struct timespec ts; 72 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 73 exit(1); 74 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 75} 76 77static void thread_start(void* (*fn)(void*), void* arg) 78{ 79 pthread_t th; 80 pthread_attr_t attr; 81 pthread_attr_init(&attr); 82 pthread_attr_setstacksize(&attr, 128 << 10); 83 int i = 0; 84 for (; i < 100; i++) { 85 if (pthread_create(&th, &attr, fn, arg) == 0) { 86 pthread_attr_destroy(&attr); 87 return; 88 } 89 if (errno == EAGAIN) { 90 usleep(50); 91 continue; 92 } 93 break; 94 } 95 exit(1); 96} 97 98typedef struct { 99 pthread_mutex_t mu; 100 pthread_cond_t cv; 101 int state; 102} event_t; 103 104static void event_init(event_t* ev) 105{ 106 if (pthread_mutex_init(&ev->mu, 0)) 107 exit(1); 108 if (pthread_cond_init(&ev->cv, 0)) 109 exit(1); 110 ev->state = 0; 111} 112 113static void event_reset(event_t* ev) 114{ 115 ev->state = 0; 116} 117 118static void event_set(event_t* ev) 119{ 120 pthread_mutex_lock(&ev->mu); 121 if (ev->state) 122 exit(1); 123 ev->state = 1; 124 pthread_mutex_unlock(&ev->mu); 125 pthread_cond_broadcast(&ev->cv); 126} 127 128static void event_wait(event_t* ev) 129{ 130 pthread_mutex_lock(&ev->mu); 131 while (!ev->state) 132 pthread_cond_wait(&ev->cv, &ev->mu); 133 pthread_mutex_unlock(&ev->mu); 134} 135 136static int event_isset(event_t* ev) 137{ 138 pthread_mutex_lock(&ev->mu); 139 int res = ev->state; 140 pthread_mutex_unlock(&ev->mu); 141 return res; 142} 143 144static int event_timedwait(event_t* ev, uint64_t timeout) 145{ 146 uint64_t start = current_time_ms(); 147 uint64_t now = start; 148 pthread_mutex_lock(&ev->mu); 149 for (;;) { 150 if (ev->state) 151 break; 152 uint64_t remain = timeout - (now - start); 153 struct timespec ts; 154 ts.tv_sec = remain / 1000; 155 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 156 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 157 now = current_time_ms(); 158 if (now - start > timeout) 159 break; 160 } 161 int res = ev->state; 162 pthread_mutex_unlock(&ev->mu); 163 return res; 164} 165 166struct thread_t { 167 int created, call; 168 event_t ready, done; 169}; 170 171static struct thread_t threads[16]; 172static void execute_call(int call); 173static int running; 174 175static void* thr(void* arg) 176{ 177 struct thread_t* th = (struct thread_t*)arg; 178 for (;;) { 179 event_wait(&th->ready); 180 event_reset(&th->ready); 181 execute_call(th->call); 182 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 183 event_set(&th->done); 184 } 185 return 0; 186} 187 188static void execute_one(void) 189{ 190 if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { 191 } 192 int i, call, thread; 193 for (call = 0; call < 5; call++) { 194 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 195 thread++) { 196 struct thread_t* th = &threads[thread]; 197 if (!th->created) { 198 th->created = 1; 199 event_init(&th->ready); 200 event_init(&th->done); 201 event_set(&th->done); 202 thread_start(thr, th); 203 } 204 if (!event_isset(&th->done)) 205 continue; 206 event_reset(&th->done); 207 th->call = call; 208 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 209 event_set(&th->ready); 210 if (call == 2) 211 break; 212 event_timedwait(&th->done, 50); 213 break; 214 } 215 } 216 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 217 sleep_ms(1); 218} 219 220static void execute_one(void); 221 222#define WAIT_FLAGS 0 223 224static void loop(void) 225{ 226 int iter = 0; 227 for (;; iter++) { 228 int pid = fork(); 229 if (pid < 0) 230 exit(1); 231 if (pid == 0) { 232 execute_one(); 233 exit(0); 234 } 235 int status = 0; 236 uint64_t start = current_time_ms(); 237 for (;;) { 238 sleep_ms(10); 239 if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 240 break; 241 if (current_time_ms() - start < 5000) 242 continue; 243 kill_and_wait(pid, &status); 244 break; 245 } 246 } 247} 248 249uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; 250 251void execute_call(int call) 252{ 253 intptr_t res = 0; 254 switch (call) { 255 case 0: 256 res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul, 257 /*proto=*/0, /*fds=*/0x200000000040ul); 258 if (res != -1) { 259 r[0] = *(uint32_t*)0x200000000040; 260 r[1] = *(uint32_t*)0x200000000044; 261 } 262 break; 263 case 1: 264 memcpy((void*)0x200000000100, "\x09\x00\x10\x00", 4); 265 syscall(SYS_setsockopt, /*fd=*/r[1], /*level=*/0, /*optname=*/3, 266 /*optval=*/0x200000000100ul, /*optlen=*/4ul); 267 break; 268 case 2: 269 *(uint64_t*)0x2000000018c0 = 0; 270 *(uint32_t*)0x2000000018c8 = 0; 271 *(uint64_t*)0x2000000018d0 = 0; 272 *(uint64_t*)0x2000000018d8 = 0; 273 *(uint64_t*)0x2000000018e0 = 0x200000001880; 274 memcpy((void*)0x200000001880, "\x10\x00\x00\x00\xff\xff\x00\x00\x06", 9); 275 *(uint64_t*)0x2000000018e8 = 0x10; 276 *(uint32_t*)0x2000000018f0 = 0; 277 syscall(SYS_sendmsg, /*fd=*/r[0], /*msg=*/0x2000000018c0ul, /*f=*/0ul); 278 for (int i = 0; i < 64; i++) { 279 syscall(SYS_sendmsg, /*fd=*/r[0], /*msg=*/0x2000000018c0ul, /*f=*/0ul); 280 } 281 break; 282 case 3: 283 syscall(SYS_writev, /*fd=*/r[0], /*vec=*/0ul, /*vlen=*/0ul); 284 for (int i = 0; i < 64; i++) { 285 syscall(SYS_writev, /*fd=*/r[0], /*vec=*/0ul, /*vlen=*/0ul); 286 } 287 break; 288 case 4: 289 syscall(SYS_setsockopt, /*fd=*/(intptr_t)-1, /*level=*/0, /*optname=*/0xa, 290 /*optval=*/0ul, /*optlen=*/0ul); 291 break; 292 } 293} 294int main(void) 295{ 296 syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, 297 /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, 298 /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, 299 /*fd=*/(intptr_t)-1, /*offset=*/0ul); 300 const char* reason; 301 (void)reason; 302 for (procid = 0; procid < 4; procid++) { 303 if (fork() == 0) { 304 loop(); 305 } 306 } 307 sleep(1000000); 308 return 0; 309} 310EOF 311mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1 312 313work=/tmp/$prog.dir 314rm -rf $work 315mkdir $work 316cd /tmp/$prog.dir 317timeout 3m /tmp/$prog > /dev/null 2>&1 318 319rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work 320exit 0 321