1#!/bin/sh 2 3# No issues seen (Looks a bit like syzkaller43.sh) 4 5[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 6 7. ../default.cfg 8set -u 9prog=$(basename "$0" .sh) 10cat > /tmp/$prog.c <<EOF 11// https://syzkaller.appspot.com/bug?id=cf4c0a08d26692dc8f22b0fcc50db08fd17dd709 12// autogenerated by syzkaller (https://github.com/google/syzkaller) 13 14#define _GNU_SOURCE 15 16#include <sys/types.h> 17 18#include <dirent.h> 19#include <errno.h> 20#include <pthread.h> 21#include <pwd.h> 22#include <setjmp.h> 23#include <signal.h> 24#include <stdarg.h> 25#include <stdbool.h> 26#include <stdint.h> 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30#include <sys/endian.h> 31#include <sys/resource.h> 32#include <sys/stat.h> 33#include <sys/syscall.h> 34#include <sys/wait.h> 35#include <time.h> 36#include <unistd.h> 37 38#ifndef SYS_aio_writev 39#define SYS_aio_writev 578 40#endif 41 42static __thread int clone_ongoing; 43static __thread int skip_segv; 44static __thread jmp_buf segv_env; 45 46static void segv_handler(int sig, siginfo_t* info, void* ctx __unused) 47{ 48 if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) { 49 exit(sig); 50 } 51 uintptr_t addr = (uintptr_t)info->si_addr; 52 const uintptr_t prog_start = 1 << 20; 53 const uintptr_t prog_end = 100 << 20; 54 int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0; 55 int valid = addr < prog_start || addr > prog_end; 56 if (sig == SIGBUS) 57 valid = 1; 58 if (skip && valid) { 59 _longjmp(segv_env, 1); 60 } 61 exit(sig); 62} 63 64static void install_segv_handler(void) 65{ 66 struct sigaction sa; 67 memset(&sa, 0, sizeof(sa)); 68 sa.sa_sigaction = segv_handler; 69 sa.sa_flags = SA_NODEFER | SA_SIGINFO; 70 sigaction(SIGSEGV, &sa, NULL); 71 sigaction(SIGBUS, &sa, NULL); 72} 73 74#define NONFAILING(...) \ 75 ({ \ 76 int ok = 1; \ 77 __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \ 78 if (_setjmp(segv_env) == 0) { \ 79 __VA_ARGS__; \ 80 } else \ 81 ok = 0; \ 82 __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \ 83 ok; \ 84 }) 85 86static void kill_and_wait(int pid, int* status) 87{ 88 kill(pid, SIGKILL); 89 while (waitpid(-1, status, 0) != pid) { 90 } 91} 92 93static void sleep_ms(uint64_t ms) 94{ 95 usleep(ms * 1000); 96} 97 98static uint64_t current_time_ms(void) 99{ 100 struct timespec ts; 101 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 102 exit(1); 103 return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; 104} 105 106static void use_temporary_dir(void) 107{ 108 char tmpdir_template[] = "./syzkaller.XXXXXX"; 109 char* tmpdir = mkdtemp(tmpdir_template); 110 if (!tmpdir) 111 exit(1); 112 if (chmod(tmpdir, 0777)) 113 exit(1); 114 if (chdir(tmpdir)) 115 exit(1); 116} 117 118static void reset_flags(const char* filename) 119{ 120 struct stat st; 121 if (lstat(filename, &st)) 122 exit(1); 123 st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE | 124 SF_APPEND | UF_APPEND); 125 if (lchflags(filename, st.st_flags)) 126 exit(1); 127} 128static void __attribute__((noinline)) remove_dir(const char* dir) 129{ 130 DIR* dp = opendir(dir); 131 if (dp == NULL) { 132 if (errno == EACCES) { 133 if (rmdir(dir)) 134 exit(1); 135 return; 136 } 137 exit(1); 138 } 139 struct dirent* ep = 0; 140 while ((ep = readdir(dp))) { 141 if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) 142 continue; 143 char filename[FILENAME_MAX]; 144 snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name); 145 struct stat st; 146 if (lstat(filename, &st)) 147 exit(1); 148 if (S_ISDIR(st.st_mode)) { 149 remove_dir(filename); 150 continue; 151 } 152 if (unlink(filename)) { 153 if (errno == EPERM) { 154 reset_flags(filename); 155 reset_flags(dir); 156 if (unlink(filename) == 0) 157 continue; 158 } 159 exit(1); 160 } 161 } 162 closedir(dp); 163 while (rmdir(dir)) { 164 if (errno == EPERM) { 165 reset_flags(dir); 166 if (rmdir(dir) == 0) 167 break; 168 } 169 exit(1); 170 } 171} 172 173static void thread_start(void* (*fn)(void*), void* arg) 174{ 175 pthread_t th; 176 pthread_attr_t attr; 177 pthread_attr_init(&attr); 178 pthread_attr_setstacksize(&attr, 128 << 10); 179 int i = 0; 180 for (; i < 100; i++) { 181 if (pthread_create(&th, &attr, fn, arg) == 0) { 182 pthread_attr_destroy(&attr); 183 return; 184 } 185 if (errno == EAGAIN) { 186 usleep(50); 187 continue; 188 } 189 break; 190 } 191 exit(1); 192} 193 194typedef struct { 195 pthread_mutex_t mu; 196 pthread_cond_t cv; 197 int state; 198} event_t; 199 200static void event_init(event_t* ev) 201{ 202 if (pthread_mutex_init(&ev->mu, 0)) 203 exit(1); 204 if (pthread_cond_init(&ev->cv, 0)) 205 exit(1); 206 ev->state = 0; 207} 208 209static void event_reset(event_t* ev) 210{ 211 ev->state = 0; 212} 213 214static void event_set(event_t* ev) 215{ 216 pthread_mutex_lock(&ev->mu); 217 if (ev->state) 218 exit(1); 219 ev->state = 1; 220 pthread_mutex_unlock(&ev->mu); 221 pthread_cond_broadcast(&ev->cv); 222} 223 224static void event_wait(event_t* ev) 225{ 226 pthread_mutex_lock(&ev->mu); 227 while (!ev->state) 228 pthread_cond_wait(&ev->cv, &ev->mu); 229 pthread_mutex_unlock(&ev->mu); 230} 231 232static int event_isset(event_t* ev) 233{ 234 pthread_mutex_lock(&ev->mu); 235 int res = ev->state; 236 pthread_mutex_unlock(&ev->mu); 237 return res; 238} 239 240static int event_timedwait(event_t* ev, uint64_t timeout) 241{ 242 uint64_t start = current_time_ms(); 243 uint64_t now = start; 244 pthread_mutex_lock(&ev->mu); 245 for (;;) { 246 if (ev->state) 247 break; 248 uint64_t remain = timeout - (now - start); 249 struct timespec ts; 250 ts.tv_sec = remain / 1000; 251 ts.tv_nsec = (remain % 1000) * 1000 * 1000; 252 pthread_cond_timedwait(&ev->cv, &ev->mu, &ts); 253 now = current_time_ms(); 254 if (now - start > timeout) 255 break; 256 } 257 int res = ev->state; 258 pthread_mutex_unlock(&ev->mu); 259 return res; 260} 261 262static void sandbox_common() 263{ 264 struct rlimit rlim; 265 rlim.rlim_cur = rlim.rlim_max = 128 << 20; 266 setrlimit(RLIMIT_AS, &rlim); 267 rlim.rlim_cur = rlim.rlim_max = 8 << 20; 268 setrlimit(RLIMIT_MEMLOCK, &rlim); 269 rlim.rlim_cur = rlim.rlim_max = 1 << 20; 270 setrlimit(RLIMIT_FSIZE, &rlim); 271 rlim.rlim_cur = rlim.rlim_max = 1 << 20; 272 setrlimit(RLIMIT_STACK, &rlim); 273 rlim.rlim_cur = rlim.rlim_max = 0; 274 setrlimit(RLIMIT_CORE, &rlim); 275 rlim.rlim_cur = rlim.rlim_max = 256; 276 setrlimit(RLIMIT_NOFILE, &rlim); 277} 278 279static void loop(); 280 281static int do_sandbox_none(void) 282{ 283 sandbox_common(); 284 loop(); 285 return 0; 286} 287 288struct thread_t { 289 int created, call; 290 event_t ready, done; 291}; 292 293static struct thread_t threads[16]; 294static void execute_call(int call); 295static int running; 296 297static void* thr(void* arg) 298{ 299 struct thread_t* th = (struct thread_t*)arg; 300 for (;;) { 301 event_wait(&th->ready); 302 event_reset(&th->ready); 303 execute_call(th->call); 304 __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED); 305 event_set(&th->done); 306 } 307 return 0; 308} 309 310static void execute_one(void) 311{ 312 if (write(1, "executing program\n", sizeof("executing program\n") - 1)) { 313 } 314 int i, call, thread; 315 for (call = 0; call < 24; call++) { 316 for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0])); 317 thread++) { 318 struct thread_t* th = &threads[thread]; 319 if (!th->created) { 320 th->created = 1; 321 event_init(&th->ready); 322 event_init(&th->done); 323 event_set(&th->done); 324 thread_start(thr, th); 325 } 326 if (!event_isset(&th->done)) 327 continue; 328 event_reset(&th->done); 329 th->call = call; 330 __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED); 331 event_set(&th->ready); 332 event_timedwait(&th->done, 50); 333 break; 334 } 335 } 336 for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++) 337 sleep_ms(1); 338} 339 340static void execute_one(void); 341 342#define WAIT_FLAGS 0 343 344static void loop(void) 345{ 346 int iter = 0; 347 for (;; iter++) { 348 char cwdbuf[32]; 349 sprintf(cwdbuf, "./%d", iter); 350 if (mkdir(cwdbuf, 0777)) 351 exit(1); 352 int pid = fork(); 353 if (pid < 0) 354 exit(1); 355 if (pid == 0) { 356 if (chdir(cwdbuf)) 357 exit(1); 358 execute_one(); 359 exit(0); 360 } 361 int status = 0; 362 uint64_t start = current_time_ms(); 363 for (;;) { 364 sleep_ms(10); 365 if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) 366 break; 367 if (current_time_ms() - start < 5000) 368 continue; 369 kill_and_wait(pid, &status); 370 break; 371 } 372 remove_dir(cwdbuf); 373 } 374} 375 376uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}; 377 378void execute_call(int call) 379{ 380 intptr_t res = 0; 381 switch (call) { 382 case 0: 383 res = syscall(SYS_socket, /*domain=AF_INET6*/ 0x1cul, 384 /*type=SOCK_STREAM*/ 1ul, /*proto=*/0); 385 if (res != -1) 386 r[0] = res; 387 break; 388 case 1: 389 NONFAILING(*(uint32_t*)0x200000c0 = 0x101); 390 syscall(SYS_setsockopt, /*fd=*/r[0], /*level=*/0xffff, 391 /*optname=SO_SNDBUF*/ 0x1001, /*optval=*/0x200000c0ul, 392 /*optlen=*/4ul); 393 break; 394 case 2: 395 NONFAILING(*(uint8_t*)0x20000140 = 0x1c); 396 NONFAILING(*(uint8_t*)0x20000141 = 0x1c); 397 NONFAILING(*(uint16_t*)0x20000142 = htobe16(0x4e23)); 398 NONFAILING(*(uint32_t*)0x20000144 = 0); 399 NONFAILING(memset((void*)0x20000148, 0, 16)); 400 NONFAILING(*(uint32_t*)0x20000158 = 0); 401 syscall(SYS_bind, /*fd=*/r[0], /*addr=*/0x20000140ul, /*addrlen=*/0x1cul); 402 break; 403 case 3: 404 NONFAILING(*(uint32_t*)0x20000500 = r[0]); 405 NONFAILING(*(uint64_t*)0x20000508 = 0); 406 NONFAILING(*(uint64_t*)0x20000510 = 0); 407 NONFAILING(*(uint64_t*)0x20000518 = 0); 408 NONFAILING(*(uint32_t*)0x20000520 = 4); 409 NONFAILING(*(uint32_t*)0x20000524 = 0); 410 NONFAILING(*(uint64_t*)0x20000528 = 0); 411 NONFAILING(*(uint32_t*)0x20000530 = 0); 412 NONFAILING(*(uint32_t*)0x20000534 = 4); 413 NONFAILING(*(uint64_t*)0x20000538 = 0x822e); 414 NONFAILING(*(uint64_t*)0x20000540 = 0); 415 NONFAILING(*(uint64_t*)0x20000548 = 0x20000340); 416 NONFAILING(*(uint32_t*)0x20000550 = 0); 417 NONFAILING(*(uint32_t*)0x20000554 = 0); 418 NONFAILING(*(uint64_t*)0x20000558 = 0xfffffffffffffffe); 419 NONFAILING(*(uint64_t*)0x20000560 = 0); 420 NONFAILING(*(uint64_t*)0x20000568 = 0x20000380); 421 NONFAILING(memcpy((void*)0x20000380, "\x3c\x88\x80", 3)); 422 syscall(SYS_aio_writev, /*iocb=*/0x20000500ul); 423 break; 424 case 4: 425 NONFAILING(*(uint8_t*)0x20000180 = 0x1c); 426 NONFAILING(*(uint8_t*)0x20000181 = 0x1c); 427 NONFAILING(*(uint16_t*)0x20000182 = htobe16(0x4e23)); 428 NONFAILING(*(uint32_t*)0x20000184 = 0); 429 NONFAILING(memset((void*)0x20000188, 0, 16)); 430 NONFAILING(*(uint32_t*)0x20000198 = 0); 431 syscall(SYS_connect, /*fd=*/r[0], /*addr=*/0x20000180ul, 432 /*addrlen=*/0x1cul); 433 break; 434 case 5: 435 NONFAILING(memset((void*)0x20000200, 14, 1)); 436 syscall(SYS_sendto, /*fd=*/r[0], /*buf=*/0x20000200ul, /*len=*/0xff66ul, 437 /*f=*/0ul, /*addr=*/0ul, /*addrlen=*/0ul); 438 break; 439 case 6: 440 syscall(SYS_sendmsg, /*fd=*/r[0], /*msg=*/0ul, /*f=*/0ul); 441 break; 442 case 7: 443 syscall(SYS_socket, /*domain=AF_INET*/ 2ul, /*type=SOCK_STREAM*/ 1ul, 444 /*proto=*/0); 445 break; 446 case 8: 447 res = syscall(SYS_socket, /*domain=*/2ul, /*type=SOCK_SEQPACKET*/ 5ul, 448 /*proto=*/0x84); 449 if (res != -1) 450 r[1] = res; 451 break; 452 case 9: 453 syscall(SYS_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0ul, 454 /*flags=O_RDWR*/ 2ul, /*mode=*/0ul); 455 break; 456 case 10: 457 syscall(SYS_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0ul, 458 /*flags=O_RDWR*/ 2ul, /*mode=*/0ul); 459 break; 460 case 11: 461 syscall(SYS_socket, /*domain=*/2ul, /*type=SOCK_SEQPACKET*/ 5ul, 462 /*proto=*/0x84); 463 break; 464 case 12: 465 syscall(SYS_socket, /*domain=*/0x1cul, /*type=*/1ul, /*proto=*/0); 466 break; 467 case 13: 468 syscall(SYS_shutdown, /*fd=*/-1, /*how=*/0ul); 469 break; 470 case 14: 471 syscall(SYS_shutdown, /*fd=*/-1, /*how=*/0ul); 472 break; 473 case 15: 474 syscall(SYS_sendto, /*fd=*/-1, /*buf=*/0ul, /*len=*/0ul, /*f=*/0ul, 475 /*addr=*/0ul, /*addrlen=*/0ul); 476 break; 477 case 16: 478 syscall(SYS_sendmsg, /*fd=*/-1, /*msg=*/0ul, /*f=*/0ul); 479 break; 480 case 17: 481 syscall(SYS_rfork, /*flags=RFMEM|RFTHREAD|RFCFDG|RFNOWAIT*/ 0x3060ul); 482 break; 483 case 18: 484 syscall(SYS_rfork, /*flags=RFMEM|RFTHREAD|RFCFDG|RFNOWAIT*/ 0x3060ul); 485 break; 486 case 19: 487 syscall(SYS_openat, /*fd=*/0xffffff9cul, /*file=*/0ul, 488 /*flags=O_APPEND*/ 8ul, /*mode=*/0ul); 489 break; 490 case 20: 491 syscall(SYS_openat, /*fd=*/0xffffff9cul, /*file=*/0ul, 492 /*flags=O_APPEND*/ 8ul, /*mode=*/0ul); 493 break; 494 case 21: 495 syscall(SYS_connect, /*fd=*/r[1], /*addr=*/0ul, /*addrlen=*/0ul); 496 break; 497 case 22: 498 res = syscall(SYS_socket, /*domain=*/2ul, /*type=SOCK_STREAM*/ 1ul, 499 /*proto=*/0x84); 500 if (res != -1) 501 r[2] = res; 502 break; 503 case 23: 504 NONFAILING(*(uint32_t*)0x200001c0 = 0); 505 syscall(SYS_getsockopt, /*fd=*/r[2], /*level=*/0x84, /*opt=*/0xc, 506 /*val=*/0ul, /*len=*/0x200001c0ul); 507 break; 508 } 509} 510int main(void) 511{ 512 syscall(SYS_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul, 513 /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, 514 /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, /*fd=*/-1, 515 /*offset=*/0ul); 516 const char* reason; 517 (void)reason; 518 install_segv_handler(); 519 use_temporary_dir(); 520 do_sandbox_none(); 521 return 0; 522} 523EOF 524mycc -o /tmp/$prog -m32 -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1 525 526(cd ../testcases/swap; ./swap -t 2m -i 10 -l 100 > /dev/null 2>&1) & 527sleep 1 528cd /tmp 529start=`date +%s` 530while [ $((`date +%s` - start)) -lt 120 ]; do 531 timeout 3m /tmp/$prog > /dev/null 2>&1 532done 533while pkill swap; do :; done 534wait 535 536rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core 537exit 0 538