1*dfc38320SPeter Holm#!/bin/sh 2*dfc38320SPeter Holm 3*dfc38320SPeter Holm# Fatal trap 12: page fault while in kernel mode 4*dfc38320SPeter Holm# cpuid = 10; apic id = 0a 5*dfc38320SPeter Holm# fault virtual address = 0x0 6*dfc38320SPeter Holm# fault code = supervisor read data, page not present 7*dfc38320SPeter Holm# instruction pointer = 0x20:0xffffffff80e04f35 8*dfc38320SPeter Holm# stack pointer = 0x28:0xfffffe014fd0fbc0 9*dfc38320SPeter Holm# frame pointer = 0x28:0xfffffe014fd0fc00 10*dfc38320SPeter Holm# code segment = base 0x0, limit 0xfffff, type 0x1b 11*dfc38320SPeter Holm# = DPL 0, pres 1, long 1, def32 0, gran 1 12*dfc38320SPeter Holm# processor eflags = interrupt enabled, resume, IOPL = 0 13*dfc38320SPeter Holm# current process = 13332 (repro77) 14*dfc38320SPeter Holm# trap number = 12 15*dfc38320SPeter Holm# panic: page fault 16*dfc38320SPeter Holm# cpuid = 10 17*dfc38320SPeter Holm# time = 1640585179 18*dfc38320SPeter Holm# KDB: stack backtrace: 19*dfc38320SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe014fd0f980 20*dfc38320SPeter Holm# vpanic() at vpanic+0x17f/frame 0xfffffe014fd0f9d0 21*dfc38320SPeter Holm# panic() at panic+0x43/frame 0xfffffe014fd0fa30 22*dfc38320SPeter Holm# trap_fatal() at trap_fatal+0x385/frame 0xfffffe014fd0fa90 23*dfc38320SPeter Holm# trap_pfault() at trap_pfault+0xab/frame 0xfffffe014fd0faf0 24*dfc38320SPeter Holm# calltrap() at calltrap+0x8/frame 0xfffffe014fd0faf0 25*dfc38320SPeter Holm# --- trap 0xc, rip = 0xffffffff80e04f35, rsp = 0xfffffe014fd0fbc0, rbp = 0xfffffe014fd0fc00 --- 26*dfc38320SPeter Holm# tcp_usr_rcvd() at tcp_usr_rcvd+0x65/frame 0xfffffe014fd0fc00 27*dfc38320SPeter Holm# soreceive_generic() at soreceive_generic+0xe44/frame 0xfffffe014fd0fcc0 28*dfc38320SPeter Holm# soreceive() at soreceive+0x4b/frame 0xfffffe014fd0fce0 29*dfc38320SPeter Holm# kern_recvit() at kern_recvit+0x1ba/frame 0xfffffe014fd0fd90 30*dfc38320SPeter Holm# sys_recvmsg() at sys_recvmsg+0x6f/frame 0xfffffe014fd0fe00 31*dfc38320SPeter Holm# amd64_syscall() at amd64_syscall+0x145/frame 0xfffffe014fd0ff30 32*dfc38320SPeter Holm# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe014fd0ff30 33*dfc38320SPeter Holm# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x8020e328a, rsp = 0x22f48, rbp = 0x22f70 --- 34*dfc38320SPeter Holm# KDB: enter: panic 35*dfc38320SPeter Holm# [ thread pid 13332 tid 103311 ] 36*dfc38320SPeter Holm# Stopped at kdb_enter+0x37: movq $0,0x128720e(%rip) 37*dfc38320SPeter Holm# db> x/s version 38*dfc38320SPeter Holm# version: FreeBSD 14.0-CURRENT #0 ufs-n251956-c3008785b91: Mon Dec 27 06:11:30 CET 2021 39*dfc38320SPeter Holm# pho@mercat1.netperf.freebsd.org:/var/tmp/deviant3/sys/amd64/compile/PHO 40*dfc38320SPeter Holm# db> 41*dfc38320SPeter Holm 42*dfc38320SPeter Holm. ../default.cfg 43*dfc38320SPeter Holm[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 44*dfc38320SPeter Holm 45*dfc38320SPeter Holmcat > /tmp/syzkaller49.c <<EOF 46*dfc38320SPeter Holm// https://syzkaller.appspot.com/bug?id=efb2e9f019f36fbc39380724a31cb0c458bb4e61 47*dfc38320SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller) 48*dfc38320SPeter Holm// Reported-by: syzbot+93c75c4618b2a4f0f0ac@syzkaller.appspotmail.com 49*dfc38320SPeter Holm 50*dfc38320SPeter Holm#define _GNU_SOURCE 51*dfc38320SPeter Holm 52*dfc38320SPeter Holm#include <errno.h> 53*dfc38320SPeter Holm#include <pthread.h> 54*dfc38320SPeter Holm#include <pwd.h> 55*dfc38320SPeter Holm#include <stdarg.h> 56*dfc38320SPeter Holm#include <stdbool.h> 57*dfc38320SPeter Holm#include <stdint.h> 58*dfc38320SPeter Holm#include <stdio.h> 59*dfc38320SPeter Holm#include <stdlib.h> 60*dfc38320SPeter Holm#include <string.h> 61*dfc38320SPeter Holm#include <sys/endian.h> 62*dfc38320SPeter Holm#include <sys/syscall.h> 63*dfc38320SPeter Holm#include <time.h> 64*dfc38320SPeter Holm#include <unistd.h> 65*dfc38320SPeter Holm 66*dfc38320SPeter Holmstatic void sleep_ms(uint64_t ms) 67*dfc38320SPeter Holm{ 68*dfc38320SPeter Holm usleep(ms * 1000); 69*dfc38320SPeter Holm} 70*dfc38320SPeter Holm 71*dfc38320SPeter Holmstatic uint64_t current_time_ms(void) 72*dfc38320SPeter Holm{ 73*dfc38320SPeter Holm struct timespec ts; 74*dfc38320SPeter Holm if (clock_gettime(CLOCK_MONOTONIC, &ts)) 75*dfc38320SPeter Holm exit(1); 76*dfc38320SPeter Holm return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 77*dfc38320SPeter Holm} 78*dfc38320SPeter Holm 79*dfc38320SPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg) 80*dfc38320SPeter Holm{ 81*dfc38320SPeter Holm pthread_t th; 82*dfc38320SPeter Holm pthread_attr_t attr; 83*dfc38320SPeter Holm pthread_attr_init(&attr); 84*dfc38320SPeter Holm pthread_attr_setstacksize(&attr, 128 << 10); 85*dfc38320SPeter Holm int i = 0; 86*dfc38320SPeter Holm for (; i < 100; i++) { 87*dfc38320SPeter Holm if (pthread_create(&th, &attr, fn, arg) == 0) { 88*dfc38320SPeter Holm pthread_attr_destroy(&attr); 89*dfc38320SPeter Holm return; 90*dfc38320SPeter Holm } 91*dfc38320SPeter Holm if (errno == EAGAIN) { 92*dfc38320SPeter Holm usleep(50); 93*dfc38320SPeter Holm continue; 94*dfc38320SPeter Holm } 95*dfc38320SPeter Holm break; 96*dfc38320SPeter Holm } 97*dfc38320SPeter Holm exit(1); 98*dfc38320SPeter Holm} 99*dfc38320SPeter Holm 100*dfc38320SPeter Holmtypedef struct { 101*dfc38320SPeter Holm pthread_mutex_t mu; 102*dfc38320SPeter Holm pthread_cond_t cv; 103*dfc38320SPeter Holm int state; 104*dfc38320SPeter Holm} event_t; 105*dfc38320SPeter Holm 106*dfc38320SPeter Holmstatic void event_init(event_t* ev) 107*dfc38320SPeter Holm{ 108*dfc38320SPeter Holm if (pthread_mutex_init(&ev->mu, 0)) 109*dfc38320SPeter Holm exit(1); 110*dfc38320SPeter Holm if (pthread_cond_init(&ev->cv, 0)) 111*dfc38320SPeter Holm exit(1); 112*dfc38320SPeter Holm ev->state = 0; 113*dfc38320SPeter Holm} 114*dfc38320SPeter Holm 115*dfc38320SPeter Holmstatic void event_reset(event_t* ev) 116*dfc38320SPeter Holm{ 117*dfc38320SPeter Holm ev->state = 0; 118*dfc38320SPeter Holm} 119*dfc38320SPeter Holm 120*dfc38320SPeter Holmstatic void event_set(event_t* ev) 121*dfc38320SPeter Holm{ 122*dfc38320SPeter Holm pthread_mutex_lock(&ev->mu); 123*dfc38320SPeter Holm if (ev->state) 124*dfc38320SPeter Holm exit(1); 125*dfc38320SPeter Holm ev->state = 1; 126*dfc38320SPeter Holm pthread_mutex_unlock(&ev->mu); 127*dfc38320SPeter Holm pthread_cond_broadcast(&ev->cv); 128*dfc38320SPeter Holm} 129*dfc38320SPeter Holm 130*dfc38320SPeter Holmstatic void event_wait(event_t* ev) 131*dfc38320SPeter Holm{ 132*dfc38320SPeter Holm pthread_mutex_lock(&ev->mu); 133*dfc38320SPeter Holm while (!ev->state) 134*dfc38320SPeter Holm pthread_cond_wait(&ev->cv, &ev->mu); 135*dfc38320SPeter Holm pthread_mutex_unlock(&ev->mu); 136*dfc38320SPeter Holm} 137*dfc38320SPeter Holm 138*dfc38320SPeter Holmstatic int event_isset(event_t* ev) 139*dfc38320SPeter Holm{ 140*dfc38320SPeter Holm pthread_mutex_lock(&ev->mu); 141*dfc38320SPeter Holm int res = ev->state; 142*dfc38320SPeter Holm pthread_mutex_unlock(&ev->mu); 143*dfc38320SPeter Holm return res; 144*dfc38320SPeter Holm} 145*dfc38320SPeter Holm 146*dfc38320SPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout) 147*dfc38320SPeter Holm{ 148*dfc38320SPeter Holm uint64_t start = current_time_ms(); 149*dfc38320SPeter Holm uint64_t now = start; 150*dfc38320SPeter Holm pthread_mutex_lock(&ev->mu); 151*dfc38320SPeter Holm for (;;) { 152*dfc38320SPeter Holm if (ev->state) 153*dfc38320SPeter Holm break; 154*dfc38320SPeter Holm uint64_t remain = timeout - (now - start); 155*dfc38320SPeter Holm struct timespec ts; 156*dfc38320SPeter Holm ts.tv_sec = remain / 1000; 157*dfc38320SPeter Holm ts.tv_nsec = (remain % 1000) * 1000 * 1000; 158*dfc38320SPeter Holm pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 159*dfc38320SPeter Holm now = current_time_ms(); 160*dfc38320SPeter Holm if (now - start > timeout) 161*dfc38320SPeter Holm break; 162*dfc38320SPeter Holm } 163*dfc38320SPeter Holm int res = ev->state; 164*dfc38320SPeter Holm pthread_mutex_unlock(&ev->mu); 165*dfc38320SPeter Holm return res; 166*dfc38320SPeter Holm} 167*dfc38320SPeter Holm 168*dfc38320SPeter Holmstruct thread_t { 169*dfc38320SPeter Holm int created, call; 170*dfc38320SPeter Holm event_t ready, done; 171*dfc38320SPeter Holm}; 172*dfc38320SPeter Holm 173*dfc38320SPeter Holmstatic struct thread_t threads[16]; 174*dfc38320SPeter Holmstatic void execute_call(int call); 175*dfc38320SPeter Holmstatic int running; 176*dfc38320SPeter Holm 177*dfc38320SPeter Holmstatic void* thr(void* arg) 178*dfc38320SPeter Holm{ 179*dfc38320SPeter Holm struct thread_t* th = (struct thread_t*)arg; 180*dfc38320SPeter Holm for (;;) { 181*dfc38320SPeter Holm event_wait(&th->ready); 182*dfc38320SPeter Holm event_reset(&th->ready); 183*dfc38320SPeter Holm execute_call(th->call); 184*dfc38320SPeter Holm __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 185*dfc38320SPeter Holm event_set(&th->done); 186*dfc38320SPeter Holm } 187*dfc38320SPeter Holm return 0; 188*dfc38320SPeter Holm} 189*dfc38320SPeter Holm 190*dfc38320SPeter Holmstatic void loop(void) 191*dfc38320SPeter Holm{ 192*dfc38320SPeter Holm int i, call, thread; 193*dfc38320SPeter Holm for (call = 0; call < 6; call++) { 194*dfc38320SPeter Holm for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 195*dfc38320SPeter Holm thread++) { 196*dfc38320SPeter Holm struct thread_t* th = &threads[thread]; 197*dfc38320SPeter Holm if (!th->created) { 198*dfc38320SPeter Holm th->created = 1; 199*dfc38320SPeter Holm event_init(&th->ready); 200*dfc38320SPeter Holm event_init(&th->done); 201*dfc38320SPeter Holm event_set(&th->done); 202*dfc38320SPeter Holm thread_start(thr, th); 203*dfc38320SPeter Holm } 204*dfc38320SPeter Holm if (!event_isset(&th->done)) 205*dfc38320SPeter Holm continue; 206*dfc38320SPeter Holm event_reset(&th->done); 207*dfc38320SPeter Holm th->call = call; 208*dfc38320SPeter Holm __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 209*dfc38320SPeter Holm event_set(&th->ready); 210*dfc38320SPeter Holm event_timedwait(&th->done, 50); 211*dfc38320SPeter Holm break; 212*dfc38320SPeter Holm } 213*dfc38320SPeter Holm } 214*dfc38320SPeter Holm for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 215*dfc38320SPeter Holm sleep_ms(1); 216*dfc38320SPeter Holm} 217*dfc38320SPeter Holm 218*dfc38320SPeter Holmuint64_t r[1] = {0xffffffffffffffff}; 219*dfc38320SPeter Holm 220*dfc38320SPeter Holmvoid execute_call(int call) 221*dfc38320SPeter Holm{ 222*dfc38320SPeter Holm intptr_t res = 0; 223*dfc38320SPeter Holm switch (call) { 224*dfc38320SPeter Holm case 0: 225*dfc38320SPeter Holm res = syscall(SYS_socket, 2ul, 1ul, 0); 226*dfc38320SPeter Holm if (res != -1) 227*dfc38320SPeter Holm r[0] = res; 228*dfc38320SPeter Holm break; 229*dfc38320SPeter Holm case 1: 230*dfc38320SPeter Holm *(uint8_t*)0x20000140 = 0x10; 231*dfc38320SPeter Holm *(uint8_t*)0x20000141 = 2; 232*dfc38320SPeter Holm *(uint16_t*)0x20000142 = htobe16(0x4e23); 233*dfc38320SPeter Holm *(uint32_t*)0x20000144 = htobe32(0x7f000001); 234*dfc38320SPeter Holm memset((void*)0x20000148, 0, 8); 235*dfc38320SPeter Holm syscall(SYS_bind, r[0], 0x20000140ul, 0x10ul); 236*dfc38320SPeter Holm break; 237*dfc38320SPeter Holm case 2: 238*dfc38320SPeter Holm *(uint8_t*)0x20000080 = 0x10; 239*dfc38320SPeter Holm *(uint8_t*)0x20000081 = 2; 240*dfc38320SPeter Holm *(uint16_t*)0x20000082 = htobe16(0x4e23); 241*dfc38320SPeter Holm *(uint32_t*)0x20000084 = htobe32(0x7f000001); 242*dfc38320SPeter Holm memset((void*)0x20000088, 0, 8); 243*dfc38320SPeter Holm syscall(SYS_sendto, r[0], 0ul, 0ul, 0ul, 0x20000080ul, 0x10ul); 244*dfc38320SPeter Holm break; 245*dfc38320SPeter Holm case 3: 246*dfc38320SPeter Holm memset((void*)0x20000100, 69, 1); 247*dfc38320SPeter Holm syscall(SYS_sendto, r[0], 0x20000100ul, 0xfda4ul, 0ul, 0ul, 0ul); 248*dfc38320SPeter Holm break; 249*dfc38320SPeter Holm case 4: 250*dfc38320SPeter Holm *(uint64_t*)0x200003c0 = 0; 251*dfc38320SPeter Holm *(uint32_t*)0x200003c8 = 0; 252*dfc38320SPeter Holm *(uint64_t*)0x200003d0 = 0x20000340; 253*dfc38320SPeter Holm *(uint64_t*)0x20000340 = 0x20000680; 254*dfc38320SPeter Holm *(uint64_t*)0x20000348 = 0x19000; 255*dfc38320SPeter Holm *(uint64_t*)0x200003d8 = 1; 256*dfc38320SPeter Holm *(uint64_t*)0x200003e0 = 0; 257*dfc38320SPeter Holm *(uint64_t*)0x200003e8 = 0; 258*dfc38320SPeter Holm *(uint32_t*)0x200003f0 = 0; 259*dfc38320SPeter Holm syscall(SYS_recvmsg, r[0], 0x200003c0ul, 0x40ul); 260*dfc38320SPeter Holm break; 261*dfc38320SPeter Holm case 5: 262*dfc38320SPeter Holm syscall(SYS_shutdown, r[0], 1ul); 263*dfc38320SPeter Holm break; 264*dfc38320SPeter Holm } 265*dfc38320SPeter Holm} 266*dfc38320SPeter Holmint main(void) 267*dfc38320SPeter Holm{ 268*dfc38320SPeter Holm syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 269*dfc38320SPeter Holm loop(); 270*dfc38320SPeter Holm return 0; 271*dfc38320SPeter Holm} 272*dfc38320SPeter HolmEOF 273*dfc38320SPeter Holm 274*dfc38320SPeter Holmset -e 275*dfc38320SPeter Holmmount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint 276*dfc38320SPeter Holm[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 277*dfc38320SPeter Holmmdconfig -a -t swap -s 5g -u $mdstart 278*dfc38320SPeter Holmnewfs $newfs_flags -n md$mdstart > /dev/null 279*dfc38320SPeter Holmmount /dev/md$mdstart $mntpoint 280*dfc38320SPeter Holmset +e 281*dfc38320SPeter Holm 282*dfc38320SPeter Holmmkdir $mntpoint/work 283*dfc38320SPeter Holmmycc -o $mntpoint/work/syzkaller49 -Wall -Wextra -O0 /tmp/syzkaller49.c -lpthread || exit 1 284*dfc38320SPeter Holm 285*dfc38320SPeter Holmstart=`date +%s` 286*dfc38320SPeter Holmwhile [ $((`date +%s` - start)) -lt 120 ]; do 287*dfc38320SPeter Holm (cd $mntpoint/work; ./syzkaller49) 288*dfc38320SPeter Holmdone 289*dfc38320SPeter Holm 290*dfc38320SPeter Holmfor i in `jot 6`; do 291*dfc38320SPeter Holm mount | grep -q "on $mntpoint " || break 292*dfc38320SPeter Holm umount $mntpoint && break || sleep 10 293*dfc38320SPeter Holm [ $i -eq 6 ] && 294*dfc38320SPeter Holm { echo FATAL; fstat -mf $mntpoint; exit 1; } 295*dfc38320SPeter Holmdone 296*dfc38320SPeter Holmmdconfig -d -u $mdstart 297*dfc38320SPeter Holm 298*dfc38320SPeter Holmrm -rf /tmp/syzkaller49.c 299*dfc38320SPeter Holmexit 0 300