1#!/bin/sh 2 3# Fatal trap 12: page fault while in kernel mode 4# cpuid = 23; apic id = 2b 5# fault virtual address = 0x0 6# fault code = supervisor read instruction, page not present 7# instruction pointer = 0x20:0x0 8# stack pointer = 0x28:0xfffffe0131d05b78 9# frame pointer = 0x28:0xfffffe0131d05bb0 10# code segment = base 0x0, limit 0xfffff, type 0x1b 11# = DPL 0, pres 1, long 1, def32 0, gran 1 12# processor eflags = interrupt enabled, resume, IOPL = 0 13# current process = 35 (soaiod1) 14# trap number = 12 15# panic: page fault 16# cpuid = 23 17# time = 1622994049 18# KDB: stack backtrace: 19# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0131d05820 20# vpanic() at vpanic+0x181/frame 0xfffffe0131d05870 21# panic() at panic+0x43/frame 0xfffffe0131d058d0 22# trap_fatal() at trap_fatal+0x387/frame 0xfffffe0131d05930 23# trap_pfault() at trap_pfault+0x97/frame 0xfffffe0131d05990 24# trap() at trap+0x294/frame 0xfffffe0131d05aa0 25# calltrap() at calltrap+0x8/frame 0xfffffe0131d05aa0 26# --- trap 0xc, rip = 0, rsp = 0xfffffe0131d05b78, rbp = 0xfffffe0131d05bb0 --- 27# ??() at 0/frame 0xfffffe0131d05bb0 28# fork_exit() at fork_exit+0x80/frame 0xfffffe0131d05bf0 29# fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe0131d05bf0 30# --- trap 0, rip = 0, rsp = 0, rbp = 0 --- 31# KDB: enter: panic 32# [ thread pid 35 tid 100272 ] 33# Stopped at kdb_enter+0x37: movq $0,0x127fb8e(%rip) 34# db> x/s version 35# version: FreeBSD 14.0-CURRENT #0 main-n247181-1b5bc3a54b6: Sat Jun 5 04:12:19 CEST 2021 36# pho@t2.osted.lan:/usr/src/sys/amd64/compile/PHO 37# db> 38 39[ `uname -p` != "amd64" ] && exit 0 40[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 41 42. ../default.cfg 43cat > /tmp/syzkaller41.c <<EOF 44// https://syzkaller.appspot.com/bug?id=4996122a5963dbffd94839880a22e4e51575ec42 45// autogenerated by syzkaller (https://github.com/google/syzkaller) 46// Reported-by: syzbot+104d8ee3430361cb2795@syzkaller.appspotmail.com 47 48#define _GNU_SOURCE 49 50#include <errno.h> 51#include <pthread.h> 52#include <pwd.h> 53#include <stdarg.h> 54#include <stdbool.h> 55#include <stdint.h> 56#include <stdio.h> 57#include <stdlib.h> 58#include <string.h> 59#include <sys/endian.h> 60#include <sys/syscall.h> 61#include <time.h> 62#include <unistd.h> 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 loop(void) 189{ 190 int i, call, thread; 191 for (call = 0; call < 4; call++) { 192 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 193 thread++) { 194 struct thread_t* th = &threads[thread]; 195 if (!th->created) { 196 th->created = 1; 197 event_init(&th->ready); 198 event_init(&th->done); 199 event_set(&th->done); 200 thread_start(thr, th); 201 } 202 if (!event_isset(&th->done)) 203 continue; 204 event_reset(&th->done); 205 th->call = call; 206 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 207 event_set(&th->ready); 208 event_timedwait(&th->done, 50); 209 break; 210 } 211 } 212 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 213 sleep_ms(1); 214} 215 216uint64_t r[1] = {0xffffffffffffffff}; 217 218void execute_call(int call) 219{ 220 intptr_t res = 0; 221 switch (call) { 222 case 0: 223 res = syscall(SYS_socket, 0x1cul, 1ul, 0); 224 if (res != -1) 225 r[0] = res; 226 break; 227 case 1: 228 *(uint32_t*)0x20000300 = r[0]; 229 *(uint64_t*)0x20000308 = 0x9a6; 230 *(uint64_t*)0x20000310 = 0; 231 *(uint64_t*)0x20000318 = 0; 232 *(uint32_t*)0x20000320 = 0xffe; 233 *(uint32_t*)0x20000324 = 0x100; 234 *(uint64_t*)0x20000328 = 0x2b8; 235 *(uint32_t*)0x20000330 = 4; 236 *(uint32_t*)0x20000334 = 0xfff; 237 *(uint64_t*)0x20000338 = 3; 238 *(uint64_t*)0x20000340 = 0x80000001; 239 *(uint64_t*)0x20000348 = 0; 240 *(uint32_t*)0x20000350 = 4; 241 *(uint32_t*)0x20000354 = 0xb; 242 *(uint64_t*)0x20000358 = 9; 243 *(uint64_t*)0x20000360 = 0xa3c5; 244 *(uint64_t*)0x20000368 = 0xfffffffffffffff7; 245 *(uint64_t*)0x20000370 = 0x8000; 246 *(uint64_t*)0x20000378 = 3; 247 *(uint64_t*)0x20000380 = 0x498c; 248 *(uint64_t*)0x20000388 = 8; 249 *(uint64_t*)0x20000390 = 4; 250 *(uint64_t*)0x20000398 = 3; 251 syscall(SYS_aio_read, 0x20000300ul); 252 break; 253 case 2: 254 *(uint8_t*)0x20000000 = 0x1c; 255 *(uint8_t*)0x20000001 = 0x1c; 256 *(uint16_t*)0x20000002 = htobe16(0x4e21); 257 *(uint32_t*)0x20000004 = 0; 258 *(uint8_t*)0x20000008 = 0xfe; 259 *(uint8_t*)0x20000009 = 0x80; 260 memset((void*)0x2000000a, 0, 12); 261 *(uint8_t*)0x20000016 = 0; 262 *(uint8_t*)0x20000017 = 0xaa; 263 *(uint32_t*)0x20000018 = 1; 264 syscall(SYS_connect, r[0], 0x20000000ul, 0x1cul); 265 break; 266 case 3: 267 syscall(SYS_shutdown, r[0], 0ul); 268 break; 269 } 270} 271int main(void) 272{ 273 syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 274 loop(); 275 return 0; 276} 277EOF 278mycc -o /tmp/syzkaller41 -Wall -Wextra -O0 /tmp/syzkaller41.c -lpthread || 279 exit 1 280 281(cd /tmp; timeout 3m ./syzkaller41) 282 283rm -rf /tmp/syzkaller41 /tmp/syzkaller41.c /tmp/syzkaller.* 284exit 0 285