1*257a750cSPeter Holm#!/bin/sh 2*257a750cSPeter Holm 3*257a750cSPeter Holm# Fatal trap 12: page fault while in kernel mode 4*257a750cSPeter Holm# cpuid = 1; apic id = 01 5*257a750cSPeter Holm# fault virtual address = 0x18 6*257a750cSPeter Holm# fault code = supervisor read data, page not present 7*257a750cSPeter Holm# instruction pointer = 0x20:0xffffffff80b69835 8*257a750cSPeter Holm# stack pointer = 0x28:0xfffffe00ff8e7d90 9*257a750cSPeter Holm# frame pointer = 0x28:0xfffffe00ff8e7d90 10*257a750cSPeter Holm# code segment = base 0x0, limit 0xfffff, type 0x1b 11*257a750cSPeter Holm# = DPL 0, pres 1, long 1, def32 0, gran 1 12*257a750cSPeter Holm# processor eflags = interrupt enabled, resume, IOPL = 0 13*257a750cSPeter Holm# current process = 0 (thread taskq) 14*257a750cSPeter Holm# rdi: 0000000000000018 rsi: 0000000000000004 rdx: ffffffff812b3f65 15*257a750cSPeter Holm# rcx: 00000000000008ba r8: fffff800044b8780 r9: fffff80003397000 16*257a750cSPeter Holm# rax: 0000000000000001 rbx: fffff8004221fa00 rbp: fffffe00ff8e7d90 17*257a750cSPeter Holm# r10: 0000000000000001 r11: fffffe00dc47b000 r12: fffffe0177ed0000 18*257a750cSPeter Holm# r13: fffff800044b8780 r14: fffff8004221f800 r15: fffff8004221f800 19*257a750cSPeter Holm# trap number = 12 20*257a750cSPeter Holm# panic: page fault 21*257a750cSPeter Holm# cpuid = 1 22*257a750cSPeter Holm# time = 1759322830 23*257a750cSPeter Holm# KDB: stack backtrace: 24*257a750cSPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00ff8e7ac0 25*257a750cSPeter Holm# vpanic() at vpanic+0x136/frame 0xfffffe00ff8e7bf0 26*257a750cSPeter Holm# panic() at panic+0x43/frame 0xfffffe00ff8e7c50 27*257a750cSPeter Holm# trap_pfault() at trap_pfault+0x47c/frame 0xfffffe00ff8e7cc0 28*257a750cSPeter Holm# calltrap() at calltrap+0x8/frame 0xfffffe00ff8e7cc0 29*257a750cSPeter Holm# --- trap 0xc, rip = 0xffffffff80b69835, rsp = 0xfffffe00ff8e7d90, rbp = 0xfffffe00ff8e7d90 --- 30*257a750cSPeter Holm# __mtx_assert() at __mtx_assert+0x35/frame 0xfffffe00ff8e7d90 31*257a750cSPeter Holm# ktls_check_rx() at ktls_check_rx+0x2f/frame 0xfffffe00ff8e7dd0 32*257a750cSPeter Holm# socantrcvmore() at socantrcvmore+0x5e/frame 0xfffffe00ff8e7df0 33*257a750cSPeter Holm# unp_gc() at unp_gc+0x5df/frame 0xfffffe00ff8e7e40 34*257a750cSPeter Holm# taskqueue_run_locked() at taskqueue_run_locked+0x1c2/frame 0xfffffe00ff8e7ec0 35*257a750cSPeter Holm# taskqueue_thread_loop() at taskqueue_thread_loop+0xd3/frame 0xfffffe00ff8e7ef0 36*257a750cSPeter Holm# fork_exit() at fork_exit+0x82/frame 0xfffffe00ff8e7f30 37*257a750cSPeter Holm# fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe00ff8e7f30 38*257a750cSPeter Holm# --- trap 0, rip = 0, rsp = 0, rbp = 0 --- 39*257a750cSPeter Holm# KDB: enter: panic 40*257a750cSPeter Holm# [ thread pid 0 tid 100045 ] 41*257a750cSPeter Holm# Stopped at kdb_enter+0x33: movq $0,0x121a9e2(%rip) 42*257a750cSPeter Holm# db> x/s version 43*257a750cSPeter Holm# version: FreeBSD 16.0-CURRENT #0 vmfqe-n280784-b7f165e45d6d: Wed Oct 1 13:48:43 CEST 2025 44*257a750cSPeter Holm# pho@mercat1.netperf.freebsd.org:/var/tmp/deviant3/sys/amd64/compile/PHO 45*257a750cSPeter Holm# db> 46*257a750cSPeter Holm 47*257a750cSPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 48*257a750cSPeter Holm 49*257a750cSPeter Holm. ../default.cfg 50*257a750cSPeter Holmset -u 51*257a750cSPeter Holmprog=$(basename "$0" .sh) 52*257a750cSPeter Holmcat > /tmp/$prog.c <<EOF 53*257a750cSPeter Holm// https://syzkaller.appspot.com/bug?id=ec40fe3e3e2b41218d1d417bc10d0be2517bf751 54*257a750cSPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller) 55*257a750cSPeter Holm// syzbot+a62883292a5c257703be@syzkaller.appspotmail.com 56*257a750cSPeter Holm 57*257a750cSPeter Holm#define _GNU_SOURCE 58*257a750cSPeter Holm 59*257a750cSPeter Holm#include <sys/types.h> 60*257a750cSPeter Holm 61*257a750cSPeter Holm#include <dirent.h> 62*257a750cSPeter Holm#include <errno.h> 63*257a750cSPeter Holm#include <pthread.h> 64*257a750cSPeter Holm#include <pwd.h> 65*257a750cSPeter Holm#include <signal.h> 66*257a750cSPeter Holm#include <stdarg.h> 67*257a750cSPeter Holm#include <stdbool.h> 68*257a750cSPeter Holm#include <stdint.h> 69*257a750cSPeter Holm#include <stdio.h> 70*257a750cSPeter Holm#include <stdlib.h> 71*257a750cSPeter Holm#include <string.h> 72*257a750cSPeter Holm#include <sys/endian.h> 73*257a750cSPeter Holm#include <sys/resource.h> 74*257a750cSPeter Holm#include <sys/stat.h> 75*257a750cSPeter Holm#include <sys/syscall.h> 76*257a750cSPeter Holm#include <sys/wait.h> 77*257a750cSPeter Holm#include <time.h> 78*257a750cSPeter Holm#include <unistd.h> 79*257a750cSPeter Holm 80*257a750cSPeter Holmstatic unsigned long long procid; 81*257a750cSPeter Holm 82*257a750cSPeter Holmstatic void kill_and_wait(int pid, int* status) 83*257a750cSPeter Holm{ 84*257a750cSPeter Holm kill(pid, SIGKILL); 85*257a750cSPeter Holm while (waitpid(-1, status, 0) != pid) { 86*257a750cSPeter Holm } 87*257a750cSPeter Holm} 88*257a750cSPeter Holm 89*257a750cSPeter Holmstatic void sleep_ms(uint64_t ms) 90*257a750cSPeter Holm{ 91*257a750cSPeter Holm usleep(ms * 1000); 92*257a750cSPeter Holm} 93*257a750cSPeter Holm 94*257a750cSPeter Holmstatic uint64_t current_time_ms(void) 95*257a750cSPeter Holm{ 96*257a750cSPeter Holm struct timespec ts; 97*257a750cSPeter Holm if (clock_gettime(CLOCK_MONOTONIC, &ts)) 98*257a750cSPeter Holm exit(1); 99*257a750cSPeter Holm return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 100*257a750cSPeter Holm} 101*257a750cSPeter Holm 102*257a750cSPeter Holmstatic void use_temporary_dir(void) 103*257a750cSPeter Holm{ 104*257a750cSPeter Holm char tmpdir_template[] = "./syzkaller.XXXXXX"; 105*257a750cSPeter Holm char* tmpdir = mkdtemp(tmpdir_template); 106*257a750cSPeter Holm if (!tmpdir) 107*257a750cSPeter Holm exit(1); 108*257a750cSPeter Holm if (chmod(tmpdir, 0777)) 109*257a750cSPeter Holm exit(1); 110*257a750cSPeter Holm if (chdir(tmpdir)) 111*257a750cSPeter Holm exit(1); 112*257a750cSPeter Holm} 113*257a750cSPeter Holm 114*257a750cSPeter Holmstatic void reset_flags(const char* filename) 115*257a750cSPeter Holm{ 116*257a750cSPeter Holm struct stat st; 117*257a750cSPeter Holm if (lstat(filename, &st)) 118*257a750cSPeter Holm exit(1); 119*257a750cSPeter Holm st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE | 120*257a750cSPeter Holm SF_APPEND | UF_APPEND); 121*257a750cSPeter Holm if (lchflags(filename, st.st_flags)) 122*257a750cSPeter Holm exit(1); 123*257a750cSPeter Holm} 124*257a750cSPeter Holmstatic void __attribute__((noinline)) remove_dir(const char* dir) 125*257a750cSPeter Holm{ 126*257a750cSPeter Holm DIR* dp = opendir(dir); 127*257a750cSPeter Holm if (dp == NULL) { 128*257a750cSPeter Holm if (errno == EACCES) { 129*257a750cSPeter Holm if (rmdir(dir)) 130*257a750cSPeter Holm exit(1); 131*257a750cSPeter Holm return; 132*257a750cSPeter Holm } 133*257a750cSPeter Holm exit(1); 134*257a750cSPeter Holm } 135*257a750cSPeter Holm struct dirent* ep = 0; 136*257a750cSPeter Holm while ((ep = readdir(dp))) { 137*257a750cSPeter Holm if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) 138*257a750cSPeter Holm continue; 139*257a750cSPeter Holm char filename[FILENAME_MAX]; 140*257a750cSPeter Holm snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name); 141*257a750cSPeter Holm struct stat st; 142*257a750cSPeter Holm if (lstat(filename, &st)) 143*257a750cSPeter Holm exit(1); 144*257a750cSPeter Holm if (S_ISDIR(st.st_mode)) { 145*257a750cSPeter Holm remove_dir(filename); 146*257a750cSPeter Holm continue; 147*257a750cSPeter Holm } 148*257a750cSPeter Holm if (unlink(filename)) { 149*257a750cSPeter Holm if (errno == EPERM) { 150*257a750cSPeter Holm reset_flags(filename); 151*257a750cSPeter Holm reset_flags(dir); 152*257a750cSPeter Holm if (unlink(filename) == 0) 153*257a750cSPeter Holm continue; 154*257a750cSPeter Holm } 155*257a750cSPeter Holm exit(1); 156*257a750cSPeter Holm } 157*257a750cSPeter Holm } 158*257a750cSPeter Holm closedir(dp); 159*257a750cSPeter Holm while (rmdir(dir)) { 160*257a750cSPeter Holm if (errno == EPERM) { 161*257a750cSPeter Holm reset_flags(dir); 162*257a750cSPeter Holm if (rmdir(dir) == 0) 163*257a750cSPeter Holm break; 164*257a750cSPeter Holm } 165*257a750cSPeter Holm exit(1); 166*257a750cSPeter Holm } 167*257a750cSPeter Holm} 168*257a750cSPeter Holm 169*257a750cSPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg) 170*257a750cSPeter Holm{ 171*257a750cSPeter Holm pthread_t th; 172*257a750cSPeter Holm pthread_attr_t attr; 173*257a750cSPeter Holm pthread_attr_init(&attr); 174*257a750cSPeter Holm pthread_attr_setstacksize(&attr, 128 << 10); 175*257a750cSPeter Holm int i = 0; 176*257a750cSPeter Holm for (; i < 100; i++) { 177*257a750cSPeter Holm if (pthread_create(&th, &attr, fn, arg) == 0) { 178*257a750cSPeter Holm pthread_attr_destroy(&attr); 179*257a750cSPeter Holm return; 180*257a750cSPeter Holm } 181*257a750cSPeter Holm if (errno == EAGAIN) { 182*257a750cSPeter Holm usleep(50); 183*257a750cSPeter Holm continue; 184*257a750cSPeter Holm } 185*257a750cSPeter Holm break; 186*257a750cSPeter Holm } 187*257a750cSPeter Holm exit(1); 188*257a750cSPeter Holm} 189*257a750cSPeter Holm 190*257a750cSPeter Holmtypedef struct { 191*257a750cSPeter Holm pthread_mutex_t mu; 192*257a750cSPeter Holm pthread_cond_t cv; 193*257a750cSPeter Holm int state; 194*257a750cSPeter Holm} event_t; 195*257a750cSPeter Holm 196*257a750cSPeter Holmstatic void event_init(event_t* ev) 197*257a750cSPeter Holm{ 198*257a750cSPeter Holm if (pthread_mutex_init(&ev->mu, 0)) 199*257a750cSPeter Holm exit(1); 200*257a750cSPeter Holm if (pthread_cond_init(&ev->cv, 0)) 201*257a750cSPeter Holm exit(1); 202*257a750cSPeter Holm ev->state = 0; 203*257a750cSPeter Holm} 204*257a750cSPeter Holm 205*257a750cSPeter Holmstatic void event_reset(event_t* ev) 206*257a750cSPeter Holm{ 207*257a750cSPeter Holm ev->state = 0; 208*257a750cSPeter Holm} 209*257a750cSPeter Holm 210*257a750cSPeter Holmstatic void event_set(event_t* ev) 211*257a750cSPeter Holm{ 212*257a750cSPeter Holm pthread_mutex_lock(&ev->mu); 213*257a750cSPeter Holm if (ev->state) 214*257a750cSPeter Holm exit(1); 215*257a750cSPeter Holm ev->state = 1; 216*257a750cSPeter Holm pthread_mutex_unlock(&ev->mu); 217*257a750cSPeter Holm pthread_cond_broadcast(&ev->cv); 218*257a750cSPeter Holm} 219*257a750cSPeter Holm 220*257a750cSPeter Holmstatic void event_wait(event_t* ev) 221*257a750cSPeter Holm{ 222*257a750cSPeter Holm pthread_mutex_lock(&ev->mu); 223*257a750cSPeter Holm while (!ev->state) 224*257a750cSPeter Holm pthread_cond_wait(&ev->cv, &ev->mu); 225*257a750cSPeter Holm pthread_mutex_unlock(&ev->mu); 226*257a750cSPeter Holm} 227*257a750cSPeter Holm 228*257a750cSPeter Holmstatic int event_isset(event_t* ev) 229*257a750cSPeter Holm{ 230*257a750cSPeter Holm pthread_mutex_lock(&ev->mu); 231*257a750cSPeter Holm int res = ev->state; 232*257a750cSPeter Holm pthread_mutex_unlock(&ev->mu); 233*257a750cSPeter Holm return res; 234*257a750cSPeter Holm} 235*257a750cSPeter Holm 236*257a750cSPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout) 237*257a750cSPeter Holm{ 238*257a750cSPeter Holm uint64_t start = current_time_ms(); 239*257a750cSPeter Holm uint64_t now = start; 240*257a750cSPeter Holm pthread_mutex_lock(&ev->mu); 241*257a750cSPeter Holm for (;;) { 242*257a750cSPeter Holm if (ev->state) 243*257a750cSPeter Holm break; 244*257a750cSPeter Holm uint64_t remain = timeout - (now - start); 245*257a750cSPeter Holm struct timespec ts; 246*257a750cSPeter Holm ts.tv_sec = remain / 1000; 247*257a750cSPeter Holm ts.tv_nsec = (remain % 1000) * 1000 * 1000; 248*257a750cSPeter Holm pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 249*257a750cSPeter Holm now = current_time_ms(); 250*257a750cSPeter Holm if (now - start > timeout) 251*257a750cSPeter Holm break; 252*257a750cSPeter Holm } 253*257a750cSPeter Holm int res = ev->state; 254*257a750cSPeter Holm pthread_mutex_unlock(&ev->mu); 255*257a750cSPeter Holm return res; 256*257a750cSPeter Holm} 257*257a750cSPeter Holm 258*257a750cSPeter Holmstatic void sandbox_common() 259*257a750cSPeter Holm{ 260*257a750cSPeter Holm struct rlimit rlim; 261*257a750cSPeter Holm rlim.rlim_cur = rlim.rlim_max = 128 << 20; 262*257a750cSPeter Holm setrlimit(RLIMIT_AS, &rlim); 263*257a750cSPeter Holm rlim.rlim_cur = rlim.rlim_max = 8 << 20; 264*257a750cSPeter Holm setrlimit(RLIMIT_MEMLOCK, &rlim); 265*257a750cSPeter Holm rlim.rlim_cur = rlim.rlim_max = 1 << 20; 266*257a750cSPeter Holm setrlimit(RLIMIT_FSIZE, &rlim); 267*257a750cSPeter Holm rlim.rlim_cur = rlim.rlim_max = 1 << 20; 268*257a750cSPeter Holm setrlimit(RLIMIT_STACK, &rlim); 269*257a750cSPeter Holm rlim.rlim_cur = rlim.rlim_max = 0; 270*257a750cSPeter Holm setrlimit(RLIMIT_CORE, &rlim); 271*257a750cSPeter Holm rlim.rlim_cur = rlim.rlim_max = 256; 272*257a750cSPeter Holm setrlimit(RLIMIT_NOFILE, &rlim); 273*257a750cSPeter Holm} 274*257a750cSPeter Holm 275*257a750cSPeter Holmstatic void loop(); 276*257a750cSPeter Holm 277*257a750cSPeter Holmstatic int do_sandbox_none(void) 278*257a750cSPeter Holm{ 279*257a750cSPeter Holm sandbox_common(); 280*257a750cSPeter Holm loop(); 281*257a750cSPeter Holm return 0; 282*257a750cSPeter Holm} 283*257a750cSPeter Holm 284*257a750cSPeter Holmstruct thread_t { 285*257a750cSPeter Holm int created, call; 286*257a750cSPeter Holm event_t ready, done; 287*257a750cSPeter Holm}; 288*257a750cSPeter Holm 289*257a750cSPeter Holmstatic struct thread_t threads[16]; 290*257a750cSPeter Holmstatic void execute_call(int call); 291*257a750cSPeter Holmstatic int running; 292*257a750cSPeter Holm 293*257a750cSPeter Holmstatic void* thr(void* arg) 294*257a750cSPeter Holm{ 295*257a750cSPeter Holm struct thread_t* th = (struct thread_t*)arg; 296*257a750cSPeter Holm for (;;) { 297*257a750cSPeter Holm event_wait(&th->ready); 298*257a750cSPeter Holm event_reset(&th->ready); 299*257a750cSPeter Holm execute_call(th->call); 300*257a750cSPeter Holm __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 301*257a750cSPeter Holm event_set(&th->done); 302*257a750cSPeter Holm } 303*257a750cSPeter Holm return 0; 304*257a750cSPeter Holm} 305*257a750cSPeter Holm 306*257a750cSPeter Holmstatic void execute_one(void) 307*257a750cSPeter Holm{ 308*257a750cSPeter Holm if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { 309*257a750cSPeter Holm } 310*257a750cSPeter Holm int i, call, thread; 311*257a750cSPeter Holm for (call = 0; call < 8; call++) { 312*257a750cSPeter Holm for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 313*257a750cSPeter Holm thread++) { 314*257a750cSPeter Holm struct thread_t* th = &threads[thread]; 315*257a750cSPeter Holm if (!th->created) { 316*257a750cSPeter Holm th->created = 1; 317*257a750cSPeter Holm event_init(&th->ready); 318*257a750cSPeter Holm event_init(&th->done); 319*257a750cSPeter Holm event_set(&th->done); 320*257a750cSPeter Holm thread_start(thr, th); 321*257a750cSPeter Holm } 322*257a750cSPeter Holm if (!event_isset(&th->done)) 323*257a750cSPeter Holm continue; 324*257a750cSPeter Holm event_reset(&th->done); 325*257a750cSPeter Holm th->call = call; 326*257a750cSPeter Holm __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 327*257a750cSPeter Holm event_set(&th->ready); 328*257a750cSPeter Holm event_timedwait(&th->done, 50); 329*257a750cSPeter Holm break; 330*257a750cSPeter Holm } 331*257a750cSPeter Holm } 332*257a750cSPeter Holm for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 333*257a750cSPeter Holm sleep_ms(1); 334*257a750cSPeter Holm} 335*257a750cSPeter Holm 336*257a750cSPeter Holmstatic void execute_one(void); 337*257a750cSPeter Holm 338*257a750cSPeter Holm#define WAIT_FLAGS 0 339*257a750cSPeter Holm 340*257a750cSPeter Holmstatic void loop(void) 341*257a750cSPeter Holm{ 342*257a750cSPeter Holm int iter = 0; 343*257a750cSPeter Holm for (;; iter++) { 344*257a750cSPeter Holm char cwdbuf[32]; 345*257a750cSPeter Holm sprintf(cwdbuf, "./%d", iter); 346*257a750cSPeter Holm if (mkdir(cwdbuf, 0777)) 347*257a750cSPeter Holm exit(1); 348*257a750cSPeter Holm int pid = fork(); 349*257a750cSPeter Holm if (pid < 0) 350*257a750cSPeter Holm exit(1); 351*257a750cSPeter Holm if (pid == 0) { 352*257a750cSPeter Holm if (chdir(cwdbuf)) 353*257a750cSPeter Holm exit(1); 354*257a750cSPeter Holm execute_one(); 355*257a750cSPeter Holm exit(0); 356*257a750cSPeter Holm } 357*257a750cSPeter Holm int status = 0; 358*257a750cSPeter Holm uint64_t start = current_time_ms(); 359*257a750cSPeter Holm for (;;) { 360*257a750cSPeter Holm sleep_ms(10); 361*257a750cSPeter Holm if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 362*257a750cSPeter Holm break; 363*257a750cSPeter Holm if (current_time_ms() - start < 5000) 364*257a750cSPeter Holm continue; 365*257a750cSPeter Holm kill_and_wait(pid, &status); 366*257a750cSPeter Holm break; 367*257a750cSPeter Holm } 368*257a750cSPeter Holm remove_dir(cwdbuf); 369*257a750cSPeter Holm } 370*257a750cSPeter Holm} 371*257a750cSPeter Holm 372*257a750cSPeter Holmuint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}; 373*257a750cSPeter Holm 374*257a750cSPeter Holmvoid execute_call(int call) 375*257a750cSPeter Holm{ 376*257a750cSPeter Holm intptr_t res = 0; 377*257a750cSPeter Holm switch (call) { 378*257a750cSPeter Holm case 0: 379*257a750cSPeter Holm // freebsd10_pipe arguments: [ 380*257a750cSPeter Holm // pipefd: ptr[out, pipefd] { 381*257a750cSPeter Holm // pipefd { 382*257a750cSPeter Holm // rfd: fd (resource) 383*257a750cSPeter Holm // wfd: fd (resource) 384*257a750cSPeter Holm // } 385*257a750cSPeter Holm // } 386*257a750cSPeter Holm // ] 387*257a750cSPeter Holm res = syscall(SYS_freebsd10_pipe, /*pipefd=*/0x2000000001c0ul); 388*257a750cSPeter Holm if (res != -1) 389*257a750cSPeter Holm r[0] = *(uint32_t*)0x2000000001c4; 390*257a750cSPeter Holm break; 391*257a750cSPeter Holm case 1: 392*257a750cSPeter Holm // close arguments: [ 393*257a750cSPeter Holm // fd: fd (resource) 394*257a750cSPeter Holm // ] 395*257a750cSPeter Holm syscall(SYS_close, /*fd=*/r[0]); 396*257a750cSPeter Holm break; 397*257a750cSPeter Holm case 2: 398*257a750cSPeter Holm // socket\$unix arguments: [ 399*257a750cSPeter Holm // domain: const = 0x1 (8 bytes) 400*257a750cSPeter Holm // type: unix_socket_type = 0x5 (8 bytes) 401*257a750cSPeter Holm // proto: const = 0x0 (1 bytes) 402*257a750cSPeter Holm // ] 403*257a750cSPeter Holm // returns sock_unix 404*257a750cSPeter Holm res = syscall(SYS_socket, /*domain=*/1ul, /*type=SOCK_SEQPACKET*/ 5ul, 405*257a750cSPeter Holm /*proto=*/0); 406*257a750cSPeter Holm if (res != -1) 407*257a750cSPeter Holm r[1] = res; 408*257a750cSPeter Holm break; 409*257a750cSPeter Holm case 3: 410*257a750cSPeter Holm // bind\$unix arguments: [ 411*257a750cSPeter Holm // fd: sock_unix (resource) 412*257a750cSPeter Holm // addr: ptr[in, sockaddr_un] { 413*257a750cSPeter Holm // union sockaddr_un { 414*257a750cSPeter Holm // file: sockaddr_un_file { 415*257a750cSPeter Holm // len: len = 0xa (1 bytes) 416*257a750cSPeter Holm // family: unix_socket_family = 0x1 (1 bytes) 417*257a750cSPeter Holm // path: buffer: {2e 2f 66 69 6c 65 31 00} (length 0x8) 418*257a750cSPeter Holm // } 419*257a750cSPeter Holm // } 420*257a750cSPeter Holm // } 421*257a750cSPeter Holm // addrlen: len = 0xa (8 bytes) 422*257a750cSPeter Holm // ] 423*257a750cSPeter Holm *(uint8_t*)0x2000000002c0 = 0xa; 424*257a750cSPeter Holm *(uint8_t*)0x2000000002c1 = 1; 425*257a750cSPeter Holm memcpy((void*)0x2000000002c2, "./file1\000", 8); 426*257a750cSPeter Holm syscall(SYS_bind, /*fd=*/r[1], /*addr=*/0x2000000002c0ul, 427*257a750cSPeter Holm /*addrlen=*/0xaul); 428*257a750cSPeter Holm break; 429*257a750cSPeter Holm case 4: 430*257a750cSPeter Holm // listen arguments: [ 431*257a750cSPeter Holm // fd: sock (resource) 432*257a750cSPeter Holm // backlog: int32 = 0xfffffffe (4 bytes) 433*257a750cSPeter Holm // ] 434*257a750cSPeter Holm syscall(SYS_listen, /*fd=*/r[1], /*backlog=*/0xfffffffe); 435*257a750cSPeter Holm break; 436*257a750cSPeter Holm case 5: 437*257a750cSPeter Holm // sendmsg\$unix arguments: [ 438*257a750cSPeter Holm // fd: sock_unix (resource) 439*257a750cSPeter Holm // msg: ptr[in, msghdr_un] { 440*257a750cSPeter Holm // msghdr_un { 441*257a750cSPeter Holm // addr: nil 442*257a750cSPeter Holm // addrlen: len = 0x0 (4 bytes) 443*257a750cSPeter Holm // pad = 0x0 (4 bytes) 444*257a750cSPeter Holm // vec: nil 445*257a750cSPeter Holm // vlen: len = 0x0 (8 bytes) 446*257a750cSPeter Holm // ctrl: ptr[inout, array[ANYUNION]] { 447*257a750cSPeter Holm // array[ANYUNION] { 448*257a750cSPeter Holm // union ANYUNION { 449*257a750cSPeter Holm // ANYBLOB: buffer: {89 00 00 00 ff ff 00 00 01} (length 0x9) 450*257a750cSPeter Holm // } 451*257a750cSPeter Holm // } 452*257a750cSPeter Holm // } 453*257a750cSPeter Holm // ctrllen: bytesize = 0x9 (8 bytes) 454*257a750cSPeter Holm // f: send_flags = 0x0 (4 bytes) 455*257a750cSPeter Holm // pad = 0x0 (4 bytes) 456*257a750cSPeter Holm // } 457*257a750cSPeter Holm // } 458*257a750cSPeter Holm // f: send_flags = 0x0 (8 bytes) 459*257a750cSPeter Holm // ] 460*257a750cSPeter Holm *(uint64_t*)0x200000000080 = 0; 461*257a750cSPeter Holm *(uint32_t*)0x200000000088 = 0; 462*257a750cSPeter Holm *(uint64_t*)0x200000000090 = 0; 463*257a750cSPeter Holm *(uint64_t*)0x200000000098 = 0; 464*257a750cSPeter Holm *(uint64_t*)0x2000000000a0 = 0x200000000000; 465*257a750cSPeter Holm memcpy((void*)0x200000000000, "\x89\x00\x00\x00\xff\xff\x00\x00\x01", 9); 466*257a750cSPeter Holm *(uint64_t*)0x2000000000a8 = 9; 467*257a750cSPeter Holm *(uint32_t*)0x2000000000b0 = 0; 468*257a750cSPeter Holm syscall(SYS_sendmsg, /*fd=*/(intptr_t)-1, /*msg=*/0x200000000080ul, 469*257a750cSPeter Holm /*f=*/0ul); 470*257a750cSPeter Holm break; 471*257a750cSPeter Holm case 6: 472*257a750cSPeter Holm // socketpair\$unix arguments: [ 473*257a750cSPeter Holm // domain: const = 0x1 (8 bytes) 474*257a750cSPeter Holm // type: unix_socket_type = 0x2 (8 bytes) 475*257a750cSPeter Holm // proto: const = 0x0 (1 bytes) 476*257a750cSPeter Holm // fds: ptr[out, unix_pair] { 477*257a750cSPeter Holm // unix_pair { 478*257a750cSPeter Holm // fd0: sock_unix (resource) 479*257a750cSPeter Holm // fd1: sock_unix (resource) 480*257a750cSPeter Holm // } 481*257a750cSPeter Holm // } 482*257a750cSPeter Holm // ] 483*257a750cSPeter Holm res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_DGRAM*/ 2ul, 484*257a750cSPeter Holm /*proto=*/0, /*fds=*/0x200000000040ul); 485*257a750cSPeter Holm if (res != -1) 486*257a750cSPeter Holm r[2] = *(uint32_t*)0x200000000040; 487*257a750cSPeter Holm break; 488*257a750cSPeter Holm case 7: 489*257a750cSPeter Holm // sendmsg arguments: [ 490*257a750cSPeter Holm // fd: sock (resource) 491*257a750cSPeter Holm // msg: ptr[in, send_msghdr] { 492*257a750cSPeter Holm // send_msghdr { 493*257a750cSPeter Holm // msg_name: nil 494*257a750cSPeter Holm // msg_namelen: len = 0x32c (4 bytes) 495*257a750cSPeter Holm // pad = 0x0 (4 bytes) 496*257a750cSPeter Holm // msg_iov: nil 497*257a750cSPeter Holm // msg_iovlen: len = 0x0 (8 bytes) 498*257a750cSPeter Holm // msg_control: ptr[in, array[cmsghdr]] { 499*257a750cSPeter Holm // array[cmsghdr] { 500*257a750cSPeter Holm // } 501*257a750cSPeter Holm // } 502*257a750cSPeter Holm // msg_controllen: bytesize = 0x90 (8 bytes) 503*257a750cSPeter Holm // msg_flags: const = 0x0 (4 bytes) 504*257a750cSPeter Holm // pad = 0x0 (4 bytes) 505*257a750cSPeter Holm // } 506*257a750cSPeter Holm // } 507*257a750cSPeter Holm // f: send_flags = 0x0 (8 bytes) 508*257a750cSPeter Holm // ] 509*257a750cSPeter Holm *(uint64_t*)0x200000000380 = 0; 510*257a750cSPeter Holm *(uint32_t*)0x200000000388 = 0x32c; 511*257a750cSPeter Holm *(uint64_t*)0x200000000390 = 0; 512*257a750cSPeter Holm *(uint64_t*)0x200000000398 = 0; 513*257a750cSPeter Holm *(uint64_t*)0x2000000003a0 = 0x200000000000; 514*257a750cSPeter Holm *(uint64_t*)0x2000000003a8 = 0x90; 515*257a750cSPeter Holm *(uint32_t*)0x2000000003b0 = 0; 516*257a750cSPeter Holm syscall(SYS_sendmsg, /*fd=*/r[2], /*msg=*/0x200000000380ul, /*f=*/0ul); 517*257a750cSPeter Holm break; 518*257a750cSPeter Holm } 519*257a750cSPeter Holm} 520*257a750cSPeter Holmint main(void) 521*257a750cSPeter Holm{ 522*257a750cSPeter Holm syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, 523*257a750cSPeter Holm /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, 524*257a750cSPeter Holm /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, 525*257a750cSPeter Holm /*fd=*/(intptr_t)-1, /*offset=*/0ul); 526*257a750cSPeter Holm const char* reason; 527*257a750cSPeter Holm (void)reason; 528*257a750cSPeter Holm for (procid = 0; procid < 4; procid++) { 529*257a750cSPeter Holm if (fork() == 0) { 530*257a750cSPeter Holm use_temporary_dir(); 531*257a750cSPeter Holm do_sandbox_none(); 532*257a750cSPeter Holm } 533*257a750cSPeter Holm } 534*257a750cSPeter Holm sleep(1000000); 535*257a750cSPeter Holm return 0; 536*257a750cSPeter Holm} 537*257a750cSPeter HolmEOF 538*257a750cSPeter Holmmycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -pthread || exit 1 539*257a750cSPeter Holm 540*257a750cSPeter Holmwork=/tmp/$prog.dir 541*257a750cSPeter Holmrm -rf $work 542*257a750cSPeter Holmmkdir $work 543*257a750cSPeter Holmcd /tmp/$prog.dir 544*257a750cSPeter Holmfor i in `jot 30`; do 545*257a750cSPeter Holm ( 546*257a750cSPeter Holm mkdir d$i 547*257a750cSPeter Holm cd d$i 548*257a750cSPeter Holm timeout 3m /tmp/$prog > /dev/null 2>&1 & 549*257a750cSPeter Holm ) 550*257a750cSPeter Holmdone 551*257a750cSPeter Holmwhile pgrep -q $prog; do sleep 2; done 552*257a750cSPeter Holmwait 553*257a750cSPeter Holm 554*257a750cSPeter Holmrm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core $work 555*257a750cSPeter Holmexit 0 556