1#!/bin/sh 2 3# panic: refcount 0xfffff8001dd678e8 wraparound 4# cpuid = 4 5# time = 1580840365 6# KDB: stack backtrace: 7# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00e56517b0 8# vpanic() at vpanic+0x185/frame 0xfffffe00e5651810 9# panic() at panic+0x43/frame 0xfffffe00e5651870 10# _refcount_update_saturated() at _refcount_update_saturated+0x15/frame 0xfffffe00e5651880 11# refcount_release_last() at refcount_release_last+0x7c/frame 0xfffffe00e56518a0 12# closef() at closef+0x1f7/frame 0xfffffe00e5651930 13# fdescfree_fds() at fdescfree_fds+0x3c/frame 0xfffffe00e5651980 14# fdescfree() at fdescfree+0x456/frame 0xfffffe00e5651a40 15# exit1() at exit1+0x4f3/frame 0xfffffe00e5651ab0 16# sys_sys_exit() at sys_sys_exit+0xd/frame 0xfffffe00e5651ac0 17# amd64_syscall() at amd64_syscall+0x2f1/frame 0xfffffe00e5651bf0 18# fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe00e5651bf0 19# --- syscall (1, FreeBSD ELF64, sys_sys_exit), rip = 0x8003d53ba, rsp = 0x7fffffffe9f8, rbp = 0x7fffffffea10 --- 20 21# Fixed by r357554 22 23. ../default.cfg 24cat > /tmp/syzkaller1.c <<EOF 25 26// https://syzkaller.appspot.com/bug?id=29c002256f2ce0d521d1ce007c74e456a37495a8 27// autogenerated by syzkaller (https://github.com/google/syzkaller) 28 29#define _GNU_SOURCE 30 31#include <errno.h> 32#include <pthread.h> 33#include <pwd.h> 34#include <stdarg.h> 35#include <stdbool.h> 36#include <stdint.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40#include <sys/endian.h> 41#include <sys/syscall.h> 42#include <time.h> 43#include <unistd.h> 44 45static void sleep_ms(uint64_t ms) 46{ 47 usleep(ms * 1000); 48} 49 50static uint64_t current_time_ms(void) 51{ 52 struct timespec ts; 53 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 54 exit(1); 55 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 56} 57 58static void thread_start(void* (*fn)(void*), void* arg) 59{ 60 pthread_t th; 61 pthread_attr_t attr; 62 pthread_attr_init(&attr); 63 pthread_attr_setstacksize(&attr, 128 << 10); 64 int i; 65 for (i = 0; i < 100; i++) { 66 if (pthread_create(&th, &attr, fn, arg) == 0) { 67 pthread_attr_destroy(&attr); 68 return; 69 } 70 if (errno == EAGAIN) { 71 usleep(50); 72 continue; 73 } 74 break; 75 } 76 exit(1); 77} 78 79typedef struct { 80 pthread_mutex_t mu; 81 pthread_cond_t cv; 82 int state; 83} event_t; 84 85static void event_init(event_t* ev) 86{ 87 if (pthread_mutex_init(&ev->mu, 0)) 88 exit(1); 89 if (pthread_cond_init(&ev->cv, 0)) 90 exit(1); 91 ev->state = 0; 92} 93 94static void event_reset(event_t* ev) 95{ 96 ev->state = 0; 97} 98 99static void event_set(event_t* ev) 100{ 101 pthread_mutex_lock(&ev->mu); 102 if (ev->state) 103 exit(1); 104 ev->state = 1; 105 pthread_mutex_unlock(&ev->mu); 106 pthread_cond_broadcast(&ev->cv); 107} 108 109static void event_wait(event_t* ev) 110{ 111 pthread_mutex_lock(&ev->mu); 112 while (!ev->state) 113 pthread_cond_wait(&ev->cv, &ev->mu); 114 pthread_mutex_unlock(&ev->mu); 115} 116 117static int event_isset(event_t* ev) 118{ 119 pthread_mutex_lock(&ev->mu); 120 int res = ev->state; 121 pthread_mutex_unlock(&ev->mu); 122 return res; 123} 124 125static int event_timedwait(event_t* ev, uint64_t timeout) 126{ 127 uint64_t start = current_time_ms(); 128 uint64_t now = start; 129 pthread_mutex_lock(&ev->mu); 130 for (;;) { 131 if (ev->state) 132 break; 133 uint64_t remain = timeout - (now - start); 134 struct timespec ts; 135 ts.tv_sec = remain / 1000; 136 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 137 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 138 now = current_time_ms(); 139 if (now - start > timeout) 140 break; 141 } 142 int res = ev->state; 143 pthread_mutex_unlock(&ev->mu); 144 return res; 145} 146 147struct thread_t { 148 int created, call; 149 event_t ready, done; 150}; 151 152static struct thread_t threads[16]; 153static void execute_call(int call); 154static int running; 155 156static void* thr(void* arg) 157{ 158 struct thread_t* th = (struct thread_t*)arg; 159 for (;;) { 160 event_wait(&th->ready); 161 event_reset(&th->ready); 162 execute_call(th->call); 163 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 164 event_set(&th->done); 165 } 166 return 0; 167} 168 169static void loop(void) 170{ 171 int i, call, thread; 172 for (call = 0; call < 7; call++) { 173 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 174 thread++) { 175 struct thread_t* th = &threads[thread]; 176 if (!th->created) { 177 th->created = 1; 178 event_init(&th->ready); 179 event_init(&th->done); 180 event_set(&th->done); 181 thread_start(thr, th); 182 } 183 if (!event_isset(&th->done)) 184 continue; 185 event_reset(&th->done); 186 th->call = call; 187 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 188 event_set(&th->ready); 189 event_timedwait(&th->done, 45); 190 break; 191 } 192 } 193 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 194 sleep_ms(1); 195} 196 197uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}; 198 199void execute_call(int call) 200{ 201 intptr_t res; 202 switch (call) { 203 case 0: 204 memcpy((void*)0x20000000, "./file0\000", 8); 205 res = syscall(SYS_open, 0x20000000ul, 0x40000400000002c2ul, 0ul); 206 if (res != -1) 207 r[0] = res; 208 break; 209 case 1: 210 res = syscall(SYS_socket, 0x1cul, 1ul, 0ul); 211 if (res != -1) 212 r[1] = res; 213 break; 214 case 2: 215 syscall(SYS_listen, r[1], 0); 216 break; 217 case 3: 218 syscall(SYS_close, r[0]); 219 break; 220 case 4: 221 syscall(SYS_accept, r[1], 0ul, 0ul); 222 break; 223 case 5: 224 res = syscall(SYS_dup2, r[0], r[1]); 225 if (res != -1) 226 r[2] = res; 227 break; 228 case 6: 229 syscall(SYS_mmap, 0x20ffd000ul, 0x1000ul, 0ul, 0x10ul, r[2], 0ul); 230 break; 231 } 232} 233int main(void) 234{ 235 syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 3ul, 0x1012ul, -1, 0ul); 236 loop(); 237 return 0; 238} 239EOF 240mycc -o /tmp/syzkaller1 -Wall -Wextra -O2 /tmp/syzkaller1.c -lpthread || 241 exit 1 242 243(cd /tmp; ./syzkaller1) 244 245rm -f /tmp/syzkaller1 /tmp/syzkaller1.c /tmp/syzkaller1.core 246exit 0 247