1#!/bin/sh 2 3# Fatal trap 18: integer divide fault while in kernel mode 4# cpuid = 0; apic id = 00 5# instruction pointer = 0x20:0xffffffff80c2f828 6# stack pointer = 0x0:0xfffffe0131a5d9e0 7# frame pointer = 0x0:0xfffffe0131a5da30 8# code segment = base 0x0, limit 0xfffff, type 0x1b 9# = DPL 0, pres 1, long 1, def32 0, gran 1 10# processor eflags = interrupt enabled, resume, IOPL = 0 11# current process = 12 (swi4: clock (0)) 12# trap number = 18 13# panic: integer divide fault 14# cpuid = 0 15# time = 1616401924 16# KDB: stack backtrace: 17# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0131a5d6f0 18# vpanic() at vpanic+0x181/frame 0xfffffe0131a5d740 19# panic() at panic+0x43/frame 0xfffffe0131a5d7a0 20# trap_fatal() at trap_fatal+0x387/frame 0xfffffe0131a5d800 21# trap() at trap+0xa4/frame 0xfffffe0131a5d910 22# calltrap() at calltrap+0x8/frame 0xfffffe0131a5d910 23# --- trap 0x12, rip = 0xffffffff80c2f828, rsp = 0xfffffe0131a5d9e0, rbp = 0xfffffe0131a5da30 --- 24# realtimer_expire() at realtimer_expire+0x1a8/frame 0xfffffe0131a5da30 25# softclock_call_cc() at softclock_call_cc+0x15d/frame 0xfffffe0131a5db00 26# softclock() at softclock+0x66/frame 0xfffffe0131a5db20 27# ithread_loop() at ithread_loop+0x279/frame 0xfffffe0131a5dbb0 28# fork_exit() at fork_exit+0x80/frame 0xfffffe0131a5dbf0 29# fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe0131a5dbf0 30# --- trap 0, rip = 0, rsp = 0, rbp = 0 --- 31# KDB: enter: panic 32# [ thread pid 12 tid 100160 ] 33# Stopped at kdb_enter+0x37: movq $0,0x1286f8e(%rip) 34# db> x/s version 35# version: FreeBSD 14.0-CURRENT #0 main-n245565-25bfa448602: Mon Mar 22 09:13:03 CET 2021 36# pho@t2.osted.lan:/usr/src/sys/amd64/compile/PHO\012 37# db> 38 39[ `uname -p` != "amd64" ] && exit 0 40 41. ../default.cfg 42cat > /tmp/syzkaller32.c <<EOF 43// https://syzkaller.appspot.com/bug?id=02c1b7d91203fd30b386eb023d4a99d1494de733 44// autogenerated by syzkaller (https://github.com/google/syzkaller) 45// Reported-by: syzbot+157b74ff493140d86eac@syzkaller.appspotmail.com 46 47#define _GNU_SOURCE 48 49#include <sys/types.h> 50 51#include <errno.h> 52#include <pthread.h> 53#include <pwd.h> 54#include <signal.h> 55#include <stdarg.h> 56#include <stdbool.h> 57#include <stdint.h> 58#include <stdio.h> 59#include <stdlib.h> 60#include <string.h> 61#include <sys/endian.h> 62#include <sys/syscall.h> 63#include <sys/wait.h> 64#include <time.h> 65#include <unistd.h> 66 67static unsigned long long procid; 68 69static void kill_and_wait(int pid, int* status) 70{ 71 kill(pid, SIGKILL); 72 while (waitpid(-1, status, 0) != pid) { 73 } 74} 75 76static void sleep_ms(uint64_t ms) 77{ 78 usleep(ms * 1000); 79} 80 81static uint64_t current_time_ms(void) 82{ 83 struct timespec ts; 84 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 85 exit(1); 86 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 87} 88 89static void thread_start(void* (*fn)(void*), void* arg) 90{ 91 pthread_t th; 92 pthread_attr_t attr; 93 pthread_attr_init(&attr); 94 pthread_attr_setstacksize(&attr, 128 << 10); 95 int i = 0; 96 for (; i < 100; i++) { 97 if (pthread_create(&th, &attr, fn, arg) == 0) { 98 pthread_attr_destroy(&attr); 99 return; 100 } 101 if (errno == EAGAIN) { 102 usleep(50); 103 continue; 104 } 105 break; 106 } 107 exit(1); 108} 109 110typedef struct { 111 pthread_mutex_t mu; 112 pthread_cond_t cv; 113 int state; 114} event_t; 115 116static void event_init(event_t* ev) 117{ 118 if (pthread_mutex_init(&ev->mu, 0)) 119 exit(1); 120 if (pthread_cond_init(&ev->cv, 0)) 121 exit(1); 122 ev->state = 0; 123} 124 125static void event_reset(event_t* ev) 126{ 127 ev->state = 0; 128} 129 130static void event_set(event_t* ev) 131{ 132 pthread_mutex_lock(&ev->mu); 133 if (ev->state) 134 exit(1); 135 ev->state = 1; 136 pthread_mutex_unlock(&ev->mu); 137 pthread_cond_broadcast(&ev->cv); 138} 139 140static void event_wait(event_t* ev) 141{ 142 pthread_mutex_lock(&ev->mu); 143 while (!ev->state) 144 pthread_cond_wait(&ev->cv, &ev->mu); 145 pthread_mutex_unlock(&ev->mu); 146} 147 148static int event_isset(event_t* ev) 149{ 150 pthread_mutex_lock(&ev->mu); 151 int res = ev->state; 152 pthread_mutex_unlock(&ev->mu); 153 return res; 154} 155 156static int event_timedwait(event_t* ev, uint64_t timeout) 157{ 158 uint64_t start = current_time_ms(); 159 uint64_t now = start; 160 pthread_mutex_lock(&ev->mu); 161 for (;;) { 162 if (ev->state) 163 break; 164 uint64_t remain = timeout - (now - start); 165 struct timespec ts; 166 ts.tv_sec = remain / 1000; 167 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 168 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 169 now = current_time_ms(); 170 if (now - start > timeout) 171 break; 172 } 173 int res = ev->state; 174 pthread_mutex_unlock(&ev->mu); 175 return res; 176} 177 178struct thread_t { 179 int created, call; 180 event_t ready, done; 181}; 182 183static struct thread_t threads[16]; 184static void execute_call(int call); 185static int running; 186 187static void* thr(void* arg) 188{ 189 struct thread_t* th = (struct thread_t*)arg; 190 for (;;) { 191 event_wait(&th->ready); 192 event_reset(&th->ready); 193 execute_call(th->call); 194 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 195 event_set(&th->done); 196 } 197 return 0; 198} 199 200static void execute_one(void) 201{ 202 int i, call, thread; 203 for (call = 0; call < 2; call++) { 204 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 205 thread++) { 206 struct thread_t* th = &threads[thread]; 207 if (!th->created) { 208 th->created = 1; 209 event_init(&th->ready); 210 event_init(&th->done); 211 event_set(&th->done); 212 thread_start(thr, th); 213 } 214 if (!event_isset(&th->done)) 215 continue; 216 event_reset(&th->done); 217 th->call = call; 218 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 219 event_set(&th->ready); 220 event_timedwait(&th->done, 50); 221 break; 222 } 223 } 224 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 225 sleep_ms(1); 226} 227 228static void execute_one(void); 229 230#define WAIT_FLAGS 0 231 232static void loop(void) 233{ 234 int iter = 0; 235 for (;; iter++) { 236 int pid = fork(); 237 if (pid < 0) 238 exit(1); 239 if (pid == 0) { 240 execute_one(); 241 exit(0); 242 } 243 int status = 0; 244 uint64_t start = current_time_ms(); 245 for (;;) { 246 if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 247 break; 248 sleep_ms(1); 249 if (current_time_ms() - start < 5000) { 250 continue; 251 } 252 kill_and_wait(pid, &status); 253 break; 254 } 255 } 256} 257 258uint64_t r[1] = {0x0}; 259 260void execute_call(int call) 261{ 262 intptr_t res = 0; 263 switch (call) { 264 case 0: 265 res = syscall(SYS_ktimer_create, 4ul, 0ul, 0x20000500ul); 266 if (res != -1) 267 r[0] = *(uint32_t*)0x20000500; 268 break; 269 case 1: 270 *(uint64_t*)0x20000100 = 0x200000000000000; 271 *(uint64_t*)0x20000108 = 0; 272 *(uint64_t*)0x20000110 = 0; 273 *(uint64_t*)0x20000118 = 0x10000; 274 syscall(SYS_ktimer_settime, r[0], 0ul, 0x20000100ul, 0ul); 275 break; 276 } 277} 278int main(void) 279{ 280 syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul); 281 for (procid = 0; procid < 4; procid++) { 282 if (fork() == 0) { 283 loop(); 284 } 285 } 286 sleep(1000000); 287 return 0; 288} 289EOF 290mycc -o /tmp/syzkaller32 -Wall -Wextra -O0 /tmp/syzkaller32.c -lpthread || 291 exit 1 292 293(cd ../testcases/swap; ./swap -t 1m -i 20 -h > /dev/null 2>&1) & 294(cd /tmp; timeout 3m ./syzkaller32) 295while pkill swap; do :; done 296wait 297 298rm -rf /tmp/syzkaller32 /tmp/syzkaller32.c /tmp/syzkaller.* 299exit 0 300