1#!/bin/sh 2 3# panic: Assertion uio->uio_resid < 0 failed at ../../../netlink/netlink_domain.c:808 4# cpuid = 8 5# time = 1759044376 6# KDB: stack backtrace: 7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0184d17a70 8# vpanic() at vpanic+0x136/frame 0xfffffe0184d17ba0 9# panic() at panic+0x43/frame 0xfffffe0184d17c00 10# nl_soreceive() at nl_soreceive+0x433/frame 0xfffffe0184d17ca0 11# soreceive() at soreceive+0x45/frame 0xfffffe0184d17cc0 12# kern_recvit() at kern_recvit+0x181/frame 0xfffffe0184d17d70 13# sys_recvfrom() at sys_recvfrom+0xa2/frame 0xfffffe0184d17e00 14# amd64_syscall() at amd64_syscall+0x169/frame 0xfffffe0184d17f30 15# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0184d17f30 16# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x822882cca, rsp = 0x823572e88, rbp = 0x823572f90 --- 17# KDB: enter: panic 18# [ thread pid 11012 tid 138112 ] 19# Stopped at $0,0x121a722(%rip) 20# db> x/s version 21# version: FreeBSD 16.0-CURRENT #0 main-n280667-52eb7e394a7e-dirty: Sun Sep 28 08:56:14 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=e33cdff88b17af77553159c4b372cac4e4bcd652 32// autogenerated by syzkaller (https://github.com/google/syzkaller) 33// syzbot+194f95f2c5fdffef1ef5@syzkaller.appspotmail.com 34 35#define _GNU_SOURCE 36 37#include <sys/types.h> 38 39#include <dirent.h> 40#include <errno.h> 41#include <pthread.h> 42#include <pwd.h> 43#include <setjmp.h> 44#include <signal.h> 45#include <stdarg.h> 46#include <stdbool.h> 47#include <stdint.h> 48#include <stdio.h> 49#include <stdlib.h> 50#include <string.h> 51#include <sys/endian.h> 52#include <sys/resource.h> 53#include <sys/stat.h> 54#include <sys/syscall.h> 55#include <sys/wait.h> 56#include <time.h> 57#include <unistd.h> 58 59static unsigned long long procid; 60 61static __thread int clone_ongoing; 62static __thread int skip_segv; 63static __thread jmp_buf segv_env; 64 65static void segv_handler(int sig, siginfo_t* info, void* ctx __unused) 66{ 67 if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) { 68 exit(sig); 69 } 70 uintptr_t addr = (uintptr_t)info->si_addr; 71 const uintptr_t prog_start = 1 << 20; 72 const uintptr_t prog_end = 100 << 20; 73 int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0; 74 int valid = addr < prog_start || addr > prog_end; 75 if (sig == SIGBUS) 76 valid = 1; 77 if (skip && valid) { 78 _longjmp(segv_env, 1); 79 } 80 exit(sig); 81} 82 83static void install_segv_handler(void) 84{ 85 struct sigaction sa; 86 memset(&sa, 0, sizeof(sa)); 87 sa.sa_sigaction = segv_handler; 88 sa.sa_flags = SA_NODEFER | SA_SIGINFO; 89 sigaction(SIGSEGV, &sa, NULL); 90 sigaction(SIGBUS, &sa, NULL); 91} 92 93#define NONFAILING(...) \ 94 ({ \ 95 int ok = 1; \ 96 __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \ 97 if (_setjmp(segv_env) == 0) { \ 98 __VA_ARGS__; \ 99 } else \ 100 ok = 0; \ 101 __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \ 102 ok; \ 103 }) 104 105static void kill_and_wait(int pid, int* status) 106{ 107 kill(pid, SIGKILL); 108 while (waitpid(-1, status, 0) != pid) { 109 } 110} 111 112static void sleep_ms(uint64_t ms) 113{ 114 usleep(ms * 1000); 115} 116 117static uint64_t current_time_ms(void) 118{ 119 struct timespec ts; 120 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 121 exit(1); 122 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 123} 124 125static void use_temporary_dir(void) 126{ 127 char tmpdir_template[] = "./syzkaller.XXXXXX"; 128 char* tmpdir = mkdtemp(tmpdir_template); 129 if (!tmpdir) 130 exit(1); 131 if (chmod(tmpdir, 0777)) 132 exit(1); 133 if (chdir(tmpdir)) 134 exit(1); 135} 136 137static void reset_flags(const char* filename) 138{ 139 struct stat st; 140 if (lstat(filename, &st)) 141 exit(1); 142 st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE | 143 SF_APPEND | UF_APPEND); 144 if (lchflags(filename, st.st_flags)) 145 exit(1); 146} 147static void __attribute__((noinline)) remove_dir(const char* dir) 148{ 149 DIR* dp = opendir(dir); 150 if (dp == NULL) { 151 if (errno == EACCES) { 152 if (rmdir(dir)) 153 exit(1); 154 return; 155 } 156 exit(1); 157 } 158 struct dirent* ep = 0; 159 while ((ep = readdir(dp))) { 160 if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) 161 continue; 162 char filename[FILENAME_MAX]; 163 snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name); 164 struct stat st; 165 if (lstat(filename, &st)) 166 exit(1); 167 if (S_ISDIR(st.st_mode)) { 168 remove_dir(filename); 169 continue; 170 } 171 if (unlink(filename)) { 172 if (errno == EPERM) { 173 reset_flags(filename); 174 reset_flags(dir); 175 if (unlink(filename) == 0) 176 continue; 177 } 178 exit(1); 179 } 180 } 181 closedir(dp); 182 while (rmdir(dir)) { 183 if (errno == EPERM) { 184 reset_flags(dir); 185 if (rmdir(dir) == 0) 186 break; 187 } 188 exit(1); 189 } 190} 191 192static void thread_start(void* (*fn)(void*), void* arg) 193{ 194 pthread_t th; 195 pthread_attr_t attr; 196 pthread_attr_init(&attr); 197 pthread_attr_setstacksize(&attr, 128 << 10); 198 int i = 0; 199 for (; i < 100; i++) { 200 if (pthread_create(&th, &attr, fn, arg) == 0) { 201 pthread_attr_destroy(&attr); 202 return; 203 } 204 if (errno == EAGAIN) { 205 usleep(50); 206 continue; 207 } 208 break; 209 } 210 exit(1); 211} 212 213typedef struct { 214 pthread_mutex_t mu; 215 pthread_cond_t cv; 216 int state; 217} event_t; 218 219static void event_init(event_t* ev) 220{ 221 if (pthread_mutex_init(&ev->mu, 0)) 222 exit(1); 223 if (pthread_cond_init(&ev->cv, 0)) 224 exit(1); 225 ev->state = 0; 226} 227 228static void event_reset(event_t* ev) 229{ 230 ev->state = 0; 231} 232 233static void event_set(event_t* ev) 234{ 235 pthread_mutex_lock(&ev->mu); 236 if (ev->state) 237 exit(1); 238 ev->state = 1; 239 pthread_mutex_unlock(&ev->mu); 240 pthread_cond_broadcast(&ev->cv); 241} 242 243static void event_wait(event_t* ev) 244{ 245 pthread_mutex_lock(&ev->mu); 246 while (!ev->state) 247 pthread_cond_wait(&ev->cv, &ev->mu); 248 pthread_mutex_unlock(&ev->mu); 249} 250 251static int event_isset(event_t* ev) 252{ 253 pthread_mutex_lock(&ev->mu); 254 int res = ev->state; 255 pthread_mutex_unlock(&ev->mu); 256 return res; 257} 258 259static int event_timedwait(event_t* ev, uint64_t timeout) 260{ 261 uint64_t start = current_time_ms(); 262 uint64_t now = start; 263 pthread_mutex_lock(&ev->mu); 264 for (;;) { 265 if (ev->state) 266 break; 267 uint64_t remain = timeout - (now - start); 268 struct timespec ts; 269 ts.tv_sec = remain / 1000; 270 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 271 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 272 now = current_time_ms(); 273 if (now - start > timeout) 274 break; 275 } 276 int res = ev->state; 277 pthread_mutex_unlock(&ev->mu); 278 return res; 279} 280 281static void sandbox_common() 282{ 283 struct rlimit rlim; 284 rlim.rlim_cur = rlim.rlim_max = 128 << 20; 285 setrlimit(RLIMIT_AS, &rlim); 286 rlim.rlim_cur = rlim.rlim_max = 8 << 20; 287 setrlimit(RLIMIT_MEMLOCK, &rlim); 288 rlim.rlim_cur = rlim.rlim_max = 1 << 20; 289 setrlimit(RLIMIT_FSIZE, &rlim); 290 rlim.rlim_cur = rlim.rlim_max = 1 << 20; 291 setrlimit(RLIMIT_STACK, &rlim); 292 rlim.rlim_cur = rlim.rlim_max = 0; 293 setrlimit(RLIMIT_CORE, &rlim); 294 rlim.rlim_cur = rlim.rlim_max = 256; 295 setrlimit(RLIMIT_NOFILE, &rlim); 296} 297 298static void loop(); 299 300static int do_sandbox_none(void) 301{ 302 sandbox_common(); 303 loop(); 304 return 0; 305} 306 307struct thread_t { 308 int created, call; 309 event_t ready, done; 310}; 311 312static struct thread_t threads[16]; 313static void execute_call(int call); 314static int running; 315 316static void* thr(void* arg) 317{ 318 struct thread_t* th = (struct thread_t*)arg; 319 for (;;) { 320 event_wait(&th->ready); 321 event_reset(&th->ready); 322 execute_call(th->call); 323 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 324 event_set(&th->done); 325 } 326 return 0; 327} 328 329static void execute_one(void) 330{ 331 if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { 332 } 333 int i, call, thread; 334 for (call = 0; call < 3; call++) { 335 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 336 thread++) { 337 struct thread_t* th = &threads[thread]; 338 if (!th->created) { 339 th->created = 1; 340 event_init(&th->ready); 341 event_init(&th->done); 342 event_set(&th->done); 343 thread_start(thr, th); 344 } 345 if (!event_isset(&th->done)) 346 continue; 347 event_reset(&th->done); 348 th->call = call; 349 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 350 event_set(&th->ready); 351 event_timedwait(&th->done, 50); 352 break; 353 } 354 } 355 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 356 sleep_ms(1); 357} 358 359static void execute_one(void); 360 361#define WAIT_FLAGS 0 362 363static void loop(void) 364{ 365 int iter = 0; 366 for (;; iter++) { 367 char cwdbuf[32]; 368 sprintf(cwdbuf, "./%d", iter); 369 if (mkdir(cwdbuf, 0777)) 370 exit(1); 371 int pid = fork(); 372 if (pid < 0) 373 exit(1); 374 if (pid == 0) { 375 if (chdir(cwdbuf)) 376 exit(1); 377 execute_one(); 378 exit(0); 379 } 380 int status = 0; 381 uint64_t start = current_time_ms(); 382 for (;;) { 383 sleep_ms(10); 384 if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 385 break; 386 if (current_time_ms() - start < 5000) 387 continue; 388 kill_and_wait(pid, &status); 389 break; 390 } 391 remove_dir(cwdbuf); 392 } 393} 394 395uint64_t r[1] = {0xffffffffffffffff}; 396 397void execute_call(int call) 398{ 399 intptr_t res = 0; 400 switch (call) { 401 case 0: 402 // socket arguments: [ 403 // domain: socket_domain = 0x26 (8 bytes) 404 // type: socket_type = 0x2 (8 bytes) 405 // proto: int8 = 0x0 (1 bytes) 406 // ] 407 // returns sock 408 res = syscall(SYS_socket, /*domain=AF_INET|0x24*/ 0x26ul, 409 /*type=SOCK_DGRAM*/ 2ul, /*proto=*/0); 410 if (res != -1) 411 r[0] = res; 412 break; 413 case 1: 414 // bind arguments: [ 415 // fd: sock (resource) 416 // addr: ptr[in, sockaddr_storage] { 417 // union sockaddr_storage { 418 // in6: sockaddr_in6 { 419 // len: len = 0x22 (1 bytes) 420 // family: const = 0x1c (1 bytes) 421 // port: proc = 0x3 (2 bytes) 422 // flow: int32 = 0x0 (4 bytes) 423 // addr: union ipv6_addr { 424 // mcast1: ipv6_addr_multicast1 { 425 // a0: const = 0xff (1 bytes) 426 // a1: const = 0x1 (1 bytes) 427 // a2: buffer: {00 00 00 00 00 00 00 00 00 00 00 00 00} (length 428 // 0xd) a3: const = 0x1 (1 bytes) 429 // } 430 // } 431 // scope: int32 = 0x0 (4 bytes) 432 // } 433 // } 434 // } 435 // addrlen: len = 0xc (8 bytes) 436 // ] 437 NONFAILING(*(uint8_t*)0x200000000040 = 0x22); 438 NONFAILING(*(uint8_t*)0x200000000041 = 0x1c); 439 NONFAILING(*(uint16_t*)0x200000000042 = htobe16(0x4e23 + procid * 4)); 440 NONFAILING(*(uint32_t*)0x200000000044 = 0); 441 NONFAILING(*(uint8_t*)0x200000000048 = -1); 442 NONFAILING(*(uint8_t*)0x200000000049 = 1); 443 NONFAILING(memset((void*)0x20000000004a, 0, 13)); 444 NONFAILING(*(uint8_t*)0x200000000057 = 1); 445 NONFAILING(*(uint32_t*)0x200000000058 = 0); 446 syscall(SYS_bind, /*fd=*/r[0], /*addr=*/0x200000000040ul, 447 /*addrlen=*/0xcul); 448 break; 449 case 2: 450 // recvfrom\$inet arguments: [ 451 // fd: sock_in (resource) 452 // buf: nil 453 // len: len = 0x51 (8 bytes) 454 // f: recv_flags = 0x401313ab1a02f21f (8 bytes) 455 // addr: nil 456 // addrlen: len = 0x0 (8 bytes) 457 // ] 458 syscall(SYS_recvfrom, /*fd=*/r[0], /*buf=*/0ul, /*len=*/0x51ul, 459 /*f=MSG_PEEK|MSG_OOB|0x401313ab1a02f21c*/ 0x401313ab1a02f21ful, 460 /*addr=*/0ul, /*addrlen=*/0ul); 461 break; 462 } 463} 464int main(void) 465{ 466 syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, 467 /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, 468 /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, 469 /*fd=*/(intptr_t)-1, /*offset=*/0ul); 470 const char* reason; 471 (void)reason; 472 install_segv_handler(); 473 for (procid = 0; procid < 4; procid++) { 474 if (fork() == 0) { 475 use_temporary_dir(); 476 do_sandbox_none(); 477 } 478 } 479 sleep(1000000); 480 return 0; 481} 482EOF 483mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -pthread || exit 1 484 485(cd ../testcases/swap; ./swap -t 5m -i 20 -l 100 > /dev/null 2>&1) & 486sleep 5 487 488work=/tmp/$prog.dir 489rm -rf $work 490mkdir $work 491cd /tmp/$prog.dir 492 493timeout 5m /tmp/$prog > /dev/null 2>&1 494 495while pkill swap; do :; done 496wait 497 498rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/syzkaller.?????? $work 499exit 0 500