1e14e0a16SPeter Holm#!/bin/sh 2e14e0a16SPeter Holm 3e14e0a16SPeter Holm# panic: td 0xfffffe014f7193a0 is not suspended 4e14e0a16SPeter Holm# cpuid = 5 5e14e0a16SPeter Holm# time = 1652003036 6e14e0a16SPeter Holm# KDB: stack backtrace: 7e14e0a16SPeter Holm# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe019a497c20 8e14e0a16SPeter Holm# vpanic() at vpanic+0x17f/frame 0xfffffe019a497c70 9e14e0a16SPeter Holm# panic() at panic+0x43/frame 0xfffffe019a497cd0 10e14e0a16SPeter Holm# thread_single() at thread_single+0x766/frame 0xfffffe019a497d40 11e14e0a16SPeter Holm# fork1() at fork1+0x1e1/frame 0xfffffe019a497da0 12e14e0a16SPeter Holm# sys_rfork() at sys_rfork+0xa4/frame 0xfffffe019a497e00 13e14e0a16SPeter Holm# amd64_syscall() at amd64_syscall+0x145/frame 0xfffffe019a497f30 14e14e0a16SPeter Holm# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe019a497f30 15e14e0a16SPeter Holm# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x82317b7da, rsp = 0x826544f48, rbp = 0x826544f70 --- 16e14e0a16SPeter Holm# KDB: enter: panic 17e14e0a16SPeter Holm# [ thread pid 17068 tid 104913 ] 18e14e0a16SPeter Holm# Stopped at kdb_enter+0x32: movq $0,0x12795f3(%rip) 19e14e0a16SPeter Holm# db> x/s version 20e14e0a16SPeter Holm# FreeBSD 14.0-CURRENT #0 main-n255381-cbbce42345c51: Sun May 8 09:55:50 CEST 2022 21e14e0a16SPeter Holm# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO 22e14e0a16SPeter Holm# db> 23e14e0a16SPeter Holm 24e14e0a16SPeter Holm[ `uname -p` != "amd64" ] && exit 0 25e14e0a16SPeter Holm 26e14e0a16SPeter Holm. ../default.cfg 27e14e0a16SPeter Holmcat > /tmp/syzkaller54.c <<EOF 28e14e0a16SPeter Holm// https://syzkaller.appspot.com/bug?id=346de481f8b814d103c440296a0adcb7ec6c46d4 29e14e0a16SPeter Holm// autogenerated by syzkaller (https://github.com/google/syzkaller) 30e14e0a16SPeter Holm// Reported-by: syzbot+9db4640d67478a0ced08@syzkaller.appspotmail.com 31e14e0a16SPeter Holm 32e14e0a16SPeter Holm#define _GNU_SOURCE 33e14e0a16SPeter Holm 34e14e0a16SPeter Holm#include <sys/types.h> 35e14e0a16SPeter Holm 36e14e0a16SPeter Holm#include <errno.h> 37e14e0a16SPeter Holm#include <pthread.h> 38e14e0a16SPeter Holm#include <pwd.h> 39e14e0a16SPeter Holm#include <signal.h> 40e14e0a16SPeter Holm#include <stdarg.h> 41e14e0a16SPeter Holm#include <stdbool.h> 42e14e0a16SPeter Holm#include <stdint.h> 43e14e0a16SPeter Holm#include <stdio.h> 44e14e0a16SPeter Holm#include <stdlib.h> 45e14e0a16SPeter Holm#include <string.h> 46e14e0a16SPeter Holm#include <sys/endian.h> 47e14e0a16SPeter Holm#include <sys/syscall.h> 48e14e0a16SPeter Holm#include <sys/wait.h> 49e14e0a16SPeter Holm#include <time.h> 50e14e0a16SPeter Holm#include <unistd.h> 51e14e0a16SPeter Holm 52e14e0a16SPeter Holmstatic unsigned long long procid; 53e14e0a16SPeter Holm 54e14e0a16SPeter Holmstatic void kill_and_wait(int pid, int* status) 55e14e0a16SPeter Holm{ 56e14e0a16SPeter Holm kill(pid, SIGKILL); 57e14e0a16SPeter Holm while (waitpid(-1, status, 0) != pid) { 58e14e0a16SPeter Holm } 59e14e0a16SPeter Holm} 60e14e0a16SPeter Holm 61e14e0a16SPeter Holmstatic void sleep_ms(uint64_t ms) 62e14e0a16SPeter Holm{ 63e14e0a16SPeter Holm usleep(ms * 1000); 64e14e0a16SPeter Holm} 65e14e0a16SPeter Holm 66e14e0a16SPeter Holmstatic uint64_t current_time_ms(void) 67e14e0a16SPeter Holm{ 68e14e0a16SPeter Holm struct timespec ts; 69e14e0a16SPeter Holm if (clock_gettime(CLOCK_MONOTONIC, &ts)) 70e14e0a16SPeter Holm exit(1); 71e14e0a16SPeter Holm return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 72e14e0a16SPeter Holm} 73e14e0a16SPeter Holm 74e14e0a16SPeter Holmstatic void thread_start(void* (*fn)(void*), void* arg) 75e14e0a16SPeter Holm{ 76e14e0a16SPeter Holm pthread_t th; 77e14e0a16SPeter Holm pthread_attr_t attr; 78e14e0a16SPeter Holm pthread_attr_init(&attr); 79e14e0a16SPeter Holm pthread_attr_setstacksize(&attr, 128 << 10); 80e14e0a16SPeter Holm int i = 0; 81e14e0a16SPeter Holm for (; i < 100; i++) { 82e14e0a16SPeter Holm if (pthread_create(&th, &attr, fn, arg) == 0) { 83e14e0a16SPeter Holm pthread_attr_destroy(&attr); 84e14e0a16SPeter Holm return; 85e14e0a16SPeter Holm } 86e14e0a16SPeter Holm if (errno == EAGAIN) { 87e14e0a16SPeter Holm usleep(50); 88e14e0a16SPeter Holm continue; 89e14e0a16SPeter Holm } 90e14e0a16SPeter Holm break; 91e14e0a16SPeter Holm } 92e14e0a16SPeter Holm exit(1); 93e14e0a16SPeter Holm} 94e14e0a16SPeter Holm 95e14e0a16SPeter Holmtypedef struct { 96e14e0a16SPeter Holm pthread_mutex_t mu; 97e14e0a16SPeter Holm pthread_cond_t cv; 98e14e0a16SPeter Holm int state; 99e14e0a16SPeter Holm} event_t; 100e14e0a16SPeter Holm 101e14e0a16SPeter Holmstatic void event_init(event_t* ev) 102e14e0a16SPeter Holm{ 103e14e0a16SPeter Holm if (pthread_mutex_init(&ev->mu, 0)) 104e14e0a16SPeter Holm exit(1); 105e14e0a16SPeter Holm if (pthread_cond_init(&ev->cv, 0)) 106e14e0a16SPeter Holm exit(1); 107e14e0a16SPeter Holm ev->state = 0; 108e14e0a16SPeter Holm} 109e14e0a16SPeter Holm 110e14e0a16SPeter Holmstatic void event_reset(event_t* ev) 111e14e0a16SPeter Holm{ 112e14e0a16SPeter Holm ev->state = 0; 113e14e0a16SPeter Holm} 114e14e0a16SPeter Holm 115e14e0a16SPeter Holmstatic void event_set(event_t* ev) 116e14e0a16SPeter Holm{ 117e14e0a16SPeter Holm pthread_mutex_lock(&ev->mu); 118e14e0a16SPeter Holm if (ev->state) 119e14e0a16SPeter Holm exit(1); 120e14e0a16SPeter Holm ev->state = 1; 121e14e0a16SPeter Holm pthread_mutex_unlock(&ev->mu); 122e14e0a16SPeter Holm pthread_cond_broadcast(&ev->cv); 123e14e0a16SPeter Holm} 124e14e0a16SPeter Holm 125e14e0a16SPeter Holmstatic void event_wait(event_t* ev) 126e14e0a16SPeter Holm{ 127e14e0a16SPeter Holm pthread_mutex_lock(&ev->mu); 128e14e0a16SPeter Holm while (!ev->state) 129e14e0a16SPeter Holm pthread_cond_wait(&ev->cv, &ev->mu); 130e14e0a16SPeter Holm pthread_mutex_unlock(&ev->mu); 131e14e0a16SPeter Holm} 132e14e0a16SPeter Holm 133e14e0a16SPeter Holmstatic int event_isset(event_t* ev) 134e14e0a16SPeter Holm{ 135e14e0a16SPeter Holm pthread_mutex_lock(&ev->mu); 136e14e0a16SPeter Holm int res = ev->state; 137e14e0a16SPeter Holm pthread_mutex_unlock(&ev->mu); 138e14e0a16SPeter Holm return res; 139e14e0a16SPeter Holm} 140e14e0a16SPeter Holm 141e14e0a16SPeter Holmstatic int event_timedwait(event_t* ev, uint64_t timeout) 142e14e0a16SPeter Holm{ 143e14e0a16SPeter Holm uint64_t start = current_time_ms(); 144e14e0a16SPeter Holm uint64_t now = start; 145e14e0a16SPeter Holm pthread_mutex_lock(&ev->mu); 146e14e0a16SPeter Holm for (;;) { 147e14e0a16SPeter Holm if (ev->state) 148e14e0a16SPeter Holm break; 149e14e0a16SPeter Holm uint64_t remain = timeout - (now - start); 150e14e0a16SPeter Holm struct timespec ts; 151e14e0a16SPeter Holm ts.tv_sec = remain / 1000; 152e14e0a16SPeter Holm ts.tv_nsec = (remain % 1000) * 1000 * 1000; 153e14e0a16SPeter Holm pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 154e14e0a16SPeter Holm now = current_time_ms(); 155e14e0a16SPeter Holm if (now - start > timeout) 156e14e0a16SPeter Holm break; 157e14e0a16SPeter Holm } 158e14e0a16SPeter Holm int res = ev->state; 159e14e0a16SPeter Holm pthread_mutex_unlock(&ev->mu); 160e14e0a16SPeter Holm return res; 161e14e0a16SPeter Holm} 162e14e0a16SPeter Holm 163e14e0a16SPeter Holmstruct thread_t { 164e14e0a16SPeter Holm int created, call; 165e14e0a16SPeter Holm event_t ready, done; 166e14e0a16SPeter Holm}; 167e14e0a16SPeter Holm 168e14e0a16SPeter Holmstatic struct thread_t threads[16]; 169e14e0a16SPeter Holmstatic void execute_call(int call); 170e14e0a16SPeter Holmstatic int running; 171e14e0a16SPeter Holm 172e14e0a16SPeter Holmstatic void* thr(void* arg) 173e14e0a16SPeter Holm{ 174e14e0a16SPeter Holm struct thread_t* th = (struct thread_t*)arg; 175e14e0a16SPeter Holm for (;;) { 176e14e0a16SPeter Holm event_wait(&th->ready); 177e14e0a16SPeter Holm event_reset(&th->ready); 178e14e0a16SPeter Holm execute_call(th->call); 179e14e0a16SPeter Holm __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 180e14e0a16SPeter Holm event_set(&th->done); 181e14e0a16SPeter Holm } 182e14e0a16SPeter Holm return 0; 183e14e0a16SPeter Holm} 184e14e0a16SPeter Holm 185e14e0a16SPeter Holmstatic void execute_one(void) 186e14e0a16SPeter Holm{ 187e14e0a16SPeter Holm int i, call, thread; 188e14e0a16SPeter Holm for (call = 0; call < 12; call++) { 189e14e0a16SPeter Holm for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 190e14e0a16SPeter Holm thread++) { 191e14e0a16SPeter Holm struct thread_t* th = &threads[thread]; 192e14e0a16SPeter Holm if (!th->created) { 193e14e0a16SPeter Holm th->created = 1; 194e14e0a16SPeter Holm event_init(&th->ready); 195e14e0a16SPeter Holm event_init(&th->done); 196e14e0a16SPeter Holm event_set(&th->done); 197e14e0a16SPeter Holm thread_start(thr, th); 198e14e0a16SPeter Holm } 199e14e0a16SPeter Holm if (!event_isset(&th->done)) 200e14e0a16SPeter Holm continue; 201e14e0a16SPeter Holm event_reset(&th->done); 202e14e0a16SPeter Holm th->call = call; 203e14e0a16SPeter Holm __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 204e14e0a16SPeter Holm event_set(&th->ready); 205e14e0a16SPeter Holm event_timedwait(&th->done, 50); 206e14e0a16SPeter Holm break; 207e14e0a16SPeter Holm } 208e14e0a16SPeter Holm } 209e14e0a16SPeter Holm for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 210e14e0a16SPeter Holm sleep_ms(1); 211e14e0a16SPeter Holm} 212e14e0a16SPeter Holm 213e14e0a16SPeter Holmstatic void execute_one(void); 214e14e0a16SPeter Holm 215e14e0a16SPeter Holm#define WAIT_FLAGS 0 216e14e0a16SPeter Holm 217e14e0a16SPeter Holmstatic void loop(void) 218e14e0a16SPeter Holm{ 219*7f658f99SPeter Holm int iter __unused = 0; 220e14e0a16SPeter Holm for (;; iter++) { 221e14e0a16SPeter Holm int pid = fork(); 222e14e0a16SPeter Holm if (pid < 0) 223e14e0a16SPeter Holm exit(1); 224e14e0a16SPeter Holm if (pid == 0) { 225e14e0a16SPeter Holm execute_one(); 226e14e0a16SPeter Holm exit(0); 227e14e0a16SPeter Holm } 228e14e0a16SPeter Holm int status = 0; 229e14e0a16SPeter Holm uint64_t start = current_time_ms(); 230e14e0a16SPeter Holm for (;;) { 231e14e0a16SPeter Holm if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 232e14e0a16SPeter Holm break; 233e14e0a16SPeter Holm sleep_ms(1); 234e14e0a16SPeter Holm if (current_time_ms() - start < 5000) 235e14e0a16SPeter Holm continue; 236e14e0a16SPeter Holm kill_and_wait(pid, &status); 237e14e0a16SPeter Holm break; 238e14e0a16SPeter Holm } 239e14e0a16SPeter Holm } 240e14e0a16SPeter Holm} 241e14e0a16SPeter Holm 242e14e0a16SPeter Holmuint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 243e14e0a16SPeter Holm 0xffffffffffffffff}; 244e14e0a16SPeter Holm 245e14e0a16SPeter Holmvoid execute_call(int call) 246e14e0a16SPeter Holm{ 247e14e0a16SPeter Holm intptr_t res = 0; 248e14e0a16SPeter Holm switch (call) { 249e14e0a16SPeter Holm case 0: 250e14e0a16SPeter Holm res = syscall(SYS_socket, 0x1cul, 1ul, 0x84); 251e14e0a16SPeter Holm if (res != -1) 252e14e0a16SPeter Holm r[0] = res; 253e14e0a16SPeter Holm break; 254e14e0a16SPeter Holm case 1: 255e14e0a16SPeter Holm syscall(SYS_connect, r[0], 0ul, 0ul); 256e14e0a16SPeter Holm break; 257e14e0a16SPeter Holm case 2: 258e14e0a16SPeter Holm res = syscall(SYS_socket, 0x1cul, 1ul, 0x84); 259e14e0a16SPeter Holm if (res != -1) 260e14e0a16SPeter Holm r[1] = res; 261e14e0a16SPeter Holm break; 262e14e0a16SPeter Holm case 3: 263e14e0a16SPeter Holm syscall(SYS_sendto, -1, 0ul, 0ul, 0ul, 0ul, 0ul); 264e14e0a16SPeter Holm break; 265e14e0a16SPeter Holm case 4: 266e14e0a16SPeter Holm syscall(SYS_dup2, r[1], -1); 267e14e0a16SPeter Holm break; 268e14e0a16SPeter Holm case 5: 269e14e0a16SPeter Holm res = syscall(SYS_dup2, -1, -1); 270e14e0a16SPeter Holm if (res != -1) 271e14e0a16SPeter Holm r[2] = res; 272e14e0a16SPeter Holm break; 273e14e0a16SPeter Holm case 6: 274e14e0a16SPeter Holm res = syscall(SYS_dup2, -1, r[2]); 275e14e0a16SPeter Holm if (res != -1) 276e14e0a16SPeter Holm r[3] = res; 277e14e0a16SPeter Holm break; 278e14e0a16SPeter Holm case 7: 279e14e0a16SPeter Holm syscall(SYS_sendmsg, r[3], 0ul, 0ul); 280e14e0a16SPeter Holm break; 281e14e0a16SPeter Holm case 8: 282e14e0a16SPeter Holm syscall(SYS_sendto, -1, 0ul, 0ul, 0ul, 0ul, 0ul); 283e14e0a16SPeter Holm break; 284e14e0a16SPeter Holm case 9: 285e14e0a16SPeter Holm memcpy((void*)0x20000100, "/dev/filemon\000", 13); 286e14e0a16SPeter Holm syscall(SYS_openat, 0xffffffffffffff9cul, 0x20000100ul, 0ul, 0ul); 287e14e0a16SPeter Holm break; 288e14e0a16SPeter Holm case 10: 289e14e0a16SPeter Holm syscall(SYS_rfork, 0x5000ul); 290e14e0a16SPeter Holm break; 291e14e0a16SPeter Holm case 11: 292e14e0a16SPeter Holm *(uint32_t*)0x20000080 = 0x13; 293e14e0a16SPeter Holm *(uint32_t*)0x20000084 = 0; 294e14e0a16SPeter Holm *(uint32_t*)0x20000088 = 0; 295e14e0a16SPeter Holm *(uint32_t*)0x2000008c = 0; 296e14e0a16SPeter Holm *(uint32_t*)0x20000090 = -1; 297e14e0a16SPeter Holm memset((void*)0x20000094, 0, 60); 298e14e0a16SPeter Holm syscall(SYS_procctl, 0ul, 0, 6ul, 0x20000080ul); 299e14e0a16SPeter Holm break; 300e14e0a16SPeter Holm } 301e14e0a16SPeter Holm} 302e14e0a16SPeter Holmint main(void) 303e14e0a16SPeter Holm{ 304e14e0a16SPeter Holm syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 305e14e0a16SPeter Holm for (procid = 0; procid < 4; procid++) { 306e14e0a16SPeter Holm if (fork() == 0) { 307e14e0a16SPeter Holm loop(); 308e14e0a16SPeter Holm } 309e14e0a16SPeter Holm } 310e14e0a16SPeter Holm sleep(1000000); 311e14e0a16SPeter Holm return 0; 312e14e0a16SPeter Holm} 313e14e0a16SPeter HolmEOF 314e14e0a16SPeter Holmmycc -o /tmp/syzkaller54 -Wall -Wextra -O0 /tmp/syzkaller54.c -l pthread || 315e14e0a16SPeter Holm exit 1 316e14e0a16SPeter Holm 317e14e0a16SPeter Holmstart=`date +%s` 318e14e0a16SPeter Holmwhile [ $((`date +%s` - start)) -lt 120 ]; do 319e14e0a16SPeter Holm (cd /tmp; timeout 3m ./syzkaller54) 320e14e0a16SPeter Holmdone 321e14e0a16SPeter Holm 322e14e0a16SPeter Holmrm -rf /tmp/syzkaller54 /tmp/syzkaller54.c /tmp/syzkaller54.core \ 323e14e0a16SPeter Holm /tmp/syzkaller.?????? 324e14e0a16SPeter Holmexit 0 325