#!/bin/sh

# panic: mutex so_rcv not owned at ../../../kern/uipc_usrreq.c:1750
# cpuid = 5
# time = 1746938647
# KDB: stack backtrace:
# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01e75c5b40
# vpanic() at vpanic+0x136/frame 0xfffffe01e75c5c70
# panic() at panic+0x43/frame 0xfffffe01e75c5cd0
# __mtx_assert() at __mtx_assert+0xa9/frame 0xfffffe01e75c5ce0
# knote() at knote+0x45/frame 0xfffffe01e75c5d30
# sowwakeup_locked() at sowwakeup_locked+0xc8/frame 0xfffffe01e75c5d50
# socantsendmore() at socantsendmore+0x4f/frame 0xfffffe01e75c5d70
# uipc_shutdown() at uipc_shutdown+0x113/frame 0xfffffe01e75c5db0
# soshutdown() at soshutdown+0x3e/frame 0xfffffe01e75c5dd0
# kern_shutdown() at kern_shutdown+0x5e/frame 0xfffffe01e75c5e00
# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe01e75c5f30
# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01e75c5f30
# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x82281772a, rsp = 0x82092efd8, rbp = 0x82092f000 ---
# KDB: enter: panic
# [ thread pid 54792 tid 1014483 ]
# Stopped at      kdb_enter+0x33: movq    $0,0x122f192(%rip)
# db> x/s version
# version: FreeBSD 15.0-CURRENT #0 main-n277201-48578dcb6b7e-dirty: Sat May 10 13:10:42 CEST 2025
# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
# db> 

[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1

. ../default.cfg
set -u
prog=$(basename "$0" .sh)
cat > /tmp/$prog.c <<EOF
// https://syzkaller.appspot.com/bug?id=ac94349a29f2efc40e9274239e4ca9b2c473a4e7
// autogenerated by syzkaller (https://github.com/google/syzkaller)
// syzkaller.appspot.com/x/repro.c?x=16c074d4580000

#define _GNU_SOURCE

#include <pwd.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/endian.h>
#include <sys/syscall.h>
#include <unistd.h>

uint64_t r[1] = {0xffffffffffffffff};

int main(void)
{
  syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
          /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
          /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
          /*fd=*/(intptr_t)-1, /*offset=*/0ul);
  const char* reason;
  (void)reason;
  intptr_t res = 0;
  if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
  }
  res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_SEQPACKET*/ 5ul,
                /*proto=*/0, /*fds=*/0x200000000040ul);
  if (res != -1)
    r[0] = *(uint32_t*)0x200000000044;
  syscall(SYS_fcntl, /*fd=*/r[0], /*cmd=*/4ul, /*flags=FASYNC*/ 0x40ul);
  syscall(SYS_shutdown, /*fd=*/r[0], /*how=*/2ul);
  return 0;
}
EOF
mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1

work=/tmp/$prog.dir
rm -rf $work
mkdir $work
cd /tmp/$prog.dir
timeout 3m /tmp/$prog > /dev/null 2>&1

rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
exit 0
