1#!/bin/sh 2 3# panic: About to free ctl:0xfffff809b0ac1260 so:0xfffff80d97dde760 and its in 1 4# cpuid = 9 5# time = 1605860285 6# KDB: stack backtrace: 7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0100b1e630 8# vpanic() at vpanic+0x182/frame 0xfffffe0100b1e680 9# panic() at panic+0x43/frame 0xfffffe0100b1e6e0 10# sctp_sorecvmsg() at sctp_sorecvmsg+0x1a96/frame 0xfffffe0100b1e810 11# sctp_soreceive() at sctp_soreceive+0x1b2/frame 0xfffffe0100b1ea00 12# soreceive() at soreceive+0x59/frame 0xfffffe0100b1ea20 13# dofileread() at dofileread+0x81/frame 0xfffffe0100b1ea70 14# sys_readv() at sys_readv+0x6e/frame 0xfffffe0100b1eac0 15# amd64_syscall() at amd64_syscall+0x147/frame 0xfffffe0100b1ebf0 16# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0100b1ebf0 17# --- syscall (0, FreeBSD ELF64, nosys), rip = 0x8003aed4a, rsp = 0x7fffdfffdf68, rbp = 0x7fffdfffdf90 --- 18# KDB: enter: panic 19# [ thread pid 3933 tid 102941 ] 20# Stopped at kdb_enter+0x37: movq $0,0x10a91b6(%rip) 21# db> x/s version 22# version: FreeBSD 13.0-CURRENT #0 r367842: Thu Nov 19 13:08:17 CET 2020 23# pho@t2.osted.lan:/usr/src/sys/amd64/compile/PHO 24# db> 25 26[ `uname -p` != "amd64" ] && exit 0 27 28. ../default.cfg 29kldstat -v | grep -q sctp || kldload sctp.ko 30 31cat > /tmp/syzkaller28.c <<EOF 32// https://syzkaller.appspot.com/bug?id=b0e5bd1e2a4ac3caf8e2ad16ae6054d9fcc2e9d2 33// autogenerated by syzkaller (https://github.com/google/syzkaller) 34// Reported-by: syzbot+b2d3e3f439385340e35f@syzkaller.appspotmail.com 35 36#define _GNU_SOURCE 37 38#include <sys/types.h> 39 40#include <errno.h> 41#include <pthread.h> 42#include <pwd.h> 43#include <signal.h> 44#include <stdarg.h> 45#include <stdbool.h> 46#include <stdint.h> 47#include <stdio.h> 48#include <stdlib.h> 49#include <string.h> 50#include <sys/endian.h> 51#include <sys/syscall.h> 52#include <sys/wait.h> 53#include <time.h> 54#include <unistd.h> 55 56static unsigned long long procid; 57 58static void kill_and_wait(int pid, int* status) 59{ 60 kill(pid, SIGKILL); 61 while (waitpid(-1, status, 0) != pid) { 62 } 63} 64 65static void sleep_ms(uint64_t ms) 66{ 67 usleep(ms * 1000); 68} 69 70static uint64_t current_time_ms(void) 71{ 72 struct timespec ts; 73 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 74 exit(1); 75 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 76} 77 78static void thread_start(void* (*fn)(void*), void* arg) 79{ 80 pthread_t th; 81 pthread_attr_t attr; 82 pthread_attr_init(&attr); 83 pthread_attr_setstacksize(&attr, 128 << 10); 84 int i = 0; 85 for (; i < 100; i++) { 86 if (pthread_create(&th, &attr, fn, arg) == 0) { 87 pthread_attr_destroy(&attr); 88 return; 89 } 90 if (errno == EAGAIN) { 91 usleep(50); 92 continue; 93 } 94 break; 95 } 96 exit(1); 97} 98 99typedef struct { 100 pthread_mutex_t mu; 101 pthread_cond_t cv; 102 int state; 103} event_t; 104 105static void event_init(event_t* ev) 106{ 107 if (pthread_mutex_init(&ev->mu, 0)) 108 exit(1); 109 if (pthread_cond_init(&ev->cv, 0)) 110 exit(1); 111 ev->state = 0; 112} 113 114static void event_reset(event_t* ev) 115{ 116 ev->state = 0; 117} 118 119static void event_set(event_t* ev) 120{ 121 pthread_mutex_lock(&ev->mu); 122 if (ev->state) 123 exit(1); 124 ev->state = 1; 125 pthread_mutex_unlock(&ev->mu); 126 pthread_cond_broadcast(&ev->cv); 127} 128 129static void event_wait(event_t* ev) 130{ 131 pthread_mutex_lock(&ev->mu); 132 while (!ev->state) 133 pthread_cond_wait(&ev->cv, &ev->mu); 134 pthread_mutex_unlock(&ev->mu); 135} 136 137static int event_isset(event_t* ev) 138{ 139 pthread_mutex_lock(&ev->mu); 140 int res = ev->state; 141 pthread_mutex_unlock(&ev->mu); 142 return res; 143} 144 145static int event_timedwait(event_t* ev, uint64_t timeout) 146{ 147 uint64_t start = current_time_ms(); 148 uint64_t now = start; 149 pthread_mutex_lock(&ev->mu); 150 for (;;) { 151 if (ev->state) 152 break; 153 uint64_t remain = timeout - (now - start); 154 struct timespec ts; 155 ts.tv_sec = remain / 1000; 156 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 157 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 158 now = current_time_ms(); 159 if (now - start > timeout) 160 break; 161 } 162 int res = ev->state; 163 pthread_mutex_unlock(&ev->mu); 164 return res; 165} 166 167struct thread_t { 168 int created, call; 169 event_t ready, done; 170}; 171 172static struct thread_t threads[16]; 173static void execute_call(int call); 174static int running; 175 176static void* thr(void* arg) 177{ 178 struct thread_t* th = (struct thread_t*)arg; 179 for (;;) { 180 event_wait(&th->ready); 181 event_reset(&th->ready); 182 execute_call(th->call); 183 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 184 event_set(&th->done); 185 } 186 return 0; 187} 188 189static void execute_one(void) 190{ 191 int i, call, thread; 192 for (call = 0; call < 9; call++) { 193 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 194 thread++) { 195 struct thread_t* th = &threads[thread]; 196 if (!th->created) { 197 th->created = 1; 198 event_init(&th->ready); 199 event_init(&th->done); 200 event_set(&th->done); 201 thread_start(thr, th); 202 } 203 if (!event_isset(&th->done)) 204 continue; 205 event_reset(&th->done); 206 th->call = call; 207 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 208 event_set(&th->ready); 209 event_timedwait(&th->done, 45); 210 break; 211 } 212 } 213 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 214 sleep_ms(1); 215} 216 217static void execute_one(void); 218 219#define WAIT_FLAGS 0 220 221static void loop(void) 222{ 223 int iter = 0; 224 for (;; iter++) { 225 int pid = fork(); 226 if (pid < 0) 227 exit(1); 228 if (pid == 0) { 229 execute_one(); 230 exit(0); 231 } 232 int status = 0; 233 uint64_t start = current_time_ms(); 234 for (;;) { 235 if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 236 break; 237 sleep_ms(1); 238 if (current_time_ms() - start < 5 * 1000) 239 continue; 240 kill_and_wait(pid, &status); 241 break; 242 } 243 } 244} 245 246uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff}; 247 248void execute_call(int call) 249{ 250 intptr_t res = 0; 251 switch (call) { 252 case 0: 253 res = syscall(SYS_socket, 0x1cul, 1ul, 0x84); 254 if (res != -1) 255 r[0] = res; 256 break; 257 case 1: 258 *(uint32_t*)0x20000040 = 0; 259 syscall(SYS_setsockopt, r[0], 0x84, 0x11, 0x20000040ul, 4ul); 260 break; 261 case 2: 262 *(uint8_t*)0x20000000 = 0x1c; 263 *(uint8_t*)0x20000001 = 0x1c; 264 *(uint16_t*)0x20000002 = htobe16(0x4e22 + procid * 4); 265 *(uint32_t*)0x20000004 = 0; 266 *(uint8_t*)0x20000008 = 0; 267 *(uint8_t*)0x20000009 = 0; 268 *(uint8_t*)0x2000000a = 0; 269 *(uint8_t*)0x2000000b = 0; 270 *(uint8_t*)0x2000000c = 0; 271 *(uint8_t*)0x2000000d = 0; 272 *(uint8_t*)0x2000000e = 0; 273 *(uint8_t*)0x2000000f = 0; 274 *(uint8_t*)0x20000010 = 0; 275 *(uint8_t*)0x20000011 = 0; 276 *(uint8_t*)0x20000012 = 0; 277 *(uint8_t*)0x20000013 = 0; 278 *(uint8_t*)0x20000014 = 0; 279 *(uint8_t*)0x20000015 = 0; 280 *(uint8_t*)0x20000016 = 0; 281 *(uint8_t*)0x20000017 = 0; 282 *(uint32_t*)0x20000018 = 6; 283 syscall(SYS_bind, r[0], 0x20000000ul, 0x1cul); 284 break; 285 case 3: 286 *(uint8_t*)0x20000180 = 0x5f; 287 *(uint8_t*)0x20000181 = 0x1c; 288 *(uint16_t*)0x20000182 = htobe16(0x4e22 + procid * 4); 289 *(uint32_t*)0x20000184 = 0; 290 *(uint64_t*)0x20000188 = htobe64(0); 291 *(uint64_t*)0x20000190 = htobe64(1); 292 *(uint32_t*)0x20000198 = 0; 293 syscall(SYS_connect, r[0], 0x20000180ul, 0x1cul); 294 break; 295 case 4: 296 *(uint64_t*)0x20001500 = 0x20000200; 297 *(uint64_t*)0x20001508 = 0xb8; 298 *(uint64_t*)0x20001510 = 0; 299 *(uint64_t*)0x20001518 = 0; 300 *(uint64_t*)0x20001520 = 0; 301 *(uint64_t*)0x20001528 = 0; 302 *(uint64_t*)0x20001530 = 0; 303 *(uint64_t*)0x20001538 = 0; 304 *(uint64_t*)0x20001540 = 0; 305 *(uint64_t*)0x20001548 = 0; 306 syscall(SYS_readv, r[0], 0x20001500ul, 5ul); 307 break; 308 case 5: 309 *(uint32_t*)0x20000140 = 0xb2; 310 syscall(SYS_setsockopt, r[0], 0x84, 0x1b, 0x20000140ul, 4ul); 311 break; 312 case 6: 313 res = syscall(SYS_fcntl, r[0], 0ul, r[0]); 314 if (res != -1) 315 r[1] = res; 316 break; 317 case 7: 318 *(uint64_t*)0x200004c0 = 0; 319 *(uint32_t*)0x200004c8 = 0; 320 *(uint64_t*)0x200004d0 = 0x200003c0; 321 *(uint64_t*)0x200003c0 = 0x200001c0; 322 memcpy((void*)0x200001c0, "\xb0", 1); 323 *(uint64_t*)0x200003c8 = 1; 324 *(uint32_t*)0x200004d8 = 1; 325 *(uint64_t*)0x200004e0 = 0; 326 *(uint32_t*)0x200004e8 = 0; 327 *(uint32_t*)0x200004ec = 0; 328 syscall(SYS_sendmsg, r[1], 0x200004c0ul, 0ul); 329 break; 330 case 8: 331 syscall(SYS_shutdown, r[0], 1ul); 332 break; 333 } 334} 335int main(void) 336{ 337 syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 338 for (procid = 0; procid < 4; procid++) { 339 if (fork() == 0) { 340 loop(); 341 } 342 } 343 sleep(1000000); 344 return 0; 345} 346EOF 347mycc -o /tmp/syzkaller28 -Wall -Wextra -O0 /tmp/syzkaller28.c -lpthread || 348 exit 1 349 350(cd ../testcases/swap; ./swap -t 1m -i 20 -h > /dev/null 2>&1) & 351(cd /tmp; timeout 3m ./syzkaller28) 352while pkill swap; do :; done 353wait 354 355rm -rf /tmp/syzkaller28 syzkaller28.c /tmp/syzkaller.* 356exit 0 357