1#!/bin/sh 2 3# panic: ktrace_enter: flag set 4# cpuid = 0 5# time = 1621577415 6# KDB: stack backtrace: 7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01c0025670 8# vpanic() at vpanic+0x181/frame 0xfffffe01c00256c0 9# panic() at panic+0x43/frame 0xfffffe01c0025720 10# ktrnamei() at ktrnamei+0xdb/frame 0xfffffe01c0025750 11# namei() at namei+0x805/frame 0xfffffe01c0025800 12# vn_open_cred() at vn_open_cred+0x497/frame 0xfffffe01c0025970 13# sys_ktrace() at sys_ktrace+0x1a0/frame 0xfffffe01c0025ac0 14# amd64_syscall() at amd64_syscall+0x147/frame 0xfffffe01c0025bf0 15# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01c0025bf0 16# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x8003b054a, rsp = 0x7fffdfffdf68, rbp = 0x7fffdfffdf90 --- 17# KDB: enter: panic 18# [ thread pid 80729 tid 101297 ] 19# Stopped at kdb_enter+0x37: movq $0,0x1281d9e(%rip) 20# db> x/s version 21# version: FreeBSD 14.0-CURRENT #0 main-n246739-fc0dc94029d-dirty: Wed May 19 05:54:45 CEST 2021 22# pho@t2.osted.lan:/usr/src/sys/amd64/compile/PHO 23# db> 24 25[ `uname -p` != "amd64" ] && exit 0 26[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 27 28. ../default.cfg 29cat > /tmp/syzkaller39.c <<EOF 30// https://syzkaller.appspot.com/bug?id=01d7251d81bbf2bf91279ecc73897961cd72beea 31// autogenerated by syzkaller (https://github.com/google/syzkaller) 32// Reported-by: syzbot+d0a4de45e58d3c08af4b@syzkaller.appspotmail.com 33 34#define _GNU_SOURCE 35 36#include <errno.h> 37#include <pthread.h> 38#include <pwd.h> 39#include <stdarg.h> 40#include <stdbool.h> 41#include <stdint.h> 42#include <stdio.h> 43#include <stdlib.h> 44#include <string.h> 45#include <sys/endian.h> 46#include <sys/syscall.h> 47#include <time.h> 48#include <unistd.h> 49 50static void sleep_ms(uint64_t ms) 51{ 52 usleep(ms * 1000); 53} 54 55static uint64_t current_time_ms(void) 56{ 57 struct timespec ts; 58 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 59 exit(1); 60 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 61} 62 63static void thread_start(void* (*fn)(void*), void* arg) 64{ 65 pthread_t th; 66 pthread_attr_t attr; 67 pthread_attr_init(&attr); 68 pthread_attr_setstacksize(&attr, 128 << 10); 69 int i = 0; 70 for (; i < 100; i++) { 71 if (pthread_create(&th, &attr, fn, arg) == 0) { 72 pthread_attr_destroy(&attr); 73 return; 74 } 75 if (errno == EAGAIN) { 76 usleep(50); 77 continue; 78 } 79 break; 80 } 81 exit(1); 82} 83 84typedef struct { 85 pthread_mutex_t mu; 86 pthread_cond_t cv; 87 int state; 88} event_t; 89 90static void event_init(event_t* ev) 91{ 92 if (pthread_mutex_init(&ev->mu, 0)) 93 exit(1); 94 if (pthread_cond_init(&ev->cv, 0)) 95 exit(1); 96 ev->state = 0; 97} 98 99static void event_reset(event_t* ev) 100{ 101 ev->state = 0; 102} 103 104static void event_set(event_t* ev) 105{ 106 pthread_mutex_lock(&ev->mu); 107 if (ev->state) 108 exit(1); 109 ev->state = 1; 110 pthread_mutex_unlock(&ev->mu); 111 pthread_cond_broadcast(&ev->cv); 112} 113 114static void event_wait(event_t* ev) 115{ 116 pthread_mutex_lock(&ev->mu); 117 while (!ev->state) 118 pthread_cond_wait(&ev->cv, &ev->mu); 119 pthread_mutex_unlock(&ev->mu); 120} 121 122static int event_isset(event_t* ev) 123{ 124 pthread_mutex_lock(&ev->mu); 125 int res = ev->state; 126 pthread_mutex_unlock(&ev->mu); 127 return res; 128} 129 130static int event_timedwait(event_t* ev, uint64_t timeout) 131{ 132 uint64_t start = current_time_ms(); 133 uint64_t now = start; 134 pthread_mutex_lock(&ev->mu); 135 for (;;) { 136 if (ev->state) 137 break; 138 uint64_t remain = timeout - (now - start); 139 struct timespec ts; 140 ts.tv_sec = remain / 1000; 141 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 142 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 143 now = current_time_ms(); 144 if (now - start > timeout) 145 break; 146 } 147 int res = ev->state; 148 pthread_mutex_unlock(&ev->mu); 149 return res; 150} 151 152struct thread_t { 153 int created, call; 154 event_t ready, done; 155}; 156 157static struct thread_t threads[16]; 158static void execute_call(int call); 159static int running; 160 161static void* thr(void* arg) 162{ 163 struct thread_t* th = (struct thread_t*)arg; 164 for (;;) { 165 event_wait(&th->ready); 166 event_reset(&th->ready); 167 execute_call(th->call); 168 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 169 event_set(&th->done); 170 } 171 return 0; 172} 173 174static void loop(void) 175{ 176 int i, call, thread; 177 int collide = 0; 178again: 179 for (call = 0; call < 3; call++) { 180 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 181 thread++) { 182 struct thread_t* th = &threads[thread]; 183 if (!th->created) { 184 th->created = 1; 185 event_init(&th->ready); 186 event_init(&th->done); 187 event_set(&th->done); 188 thread_start(thr, th); 189 } 190 if (!event_isset(&th->done)) 191 continue; 192 event_reset(&th->done); 193 th->call = call; 194 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 195 event_set(&th->ready); 196 if (collide && (call % 2) == 0) 197 break; 198 event_timedwait(&th->done, 50); 199 break; 200 } 201 } 202 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 203 sleep_ms(1); 204 if (!collide) { 205 collide = 1; 206 goto again; 207 } 208} 209 210uint64_t r[1] = {0x0}; 211 212void execute_call(int call) 213{ 214 intptr_t res = 0; 215 switch (call) { 216 case 0: 217 memcpy((void*)0x20000140, "./file0\000", 8); 218 syscall(SYS_open, 0x20000140ul, 0x200ul, 0ul); 219 break; 220 case 1: 221 res = syscall(SYS_getpid); 222 if (res != -1) 223 r[0] = res; 224 break; 225 case 2: 226 memcpy((void*)0x20000040, "./file0\000", 8); 227 syscall(SYS_ktrace, 0x20000040ul, 0ul, 0x4722db8820f38dbbul, r[0]); 228 break; 229 } 230} 231int main(void) 232{ 233 syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 234 loop(); 235 return 0; 236} 237EOF 238mycc -o /tmp/syzkaller39 -Wall -Wextra -O0 /tmp/syzkaller39.c -lpthread || 239 exit 1 240 241(cd /tmp; timeout 3m ./syzkaller39) 242 243rm -rf /tmp/syzkaller39 /tmp/syzkaller39.c /tmp/syzkaller.* 244exit 0 245