1 /*- 2 * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 /* Call random system calls with random arguments */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <sys/stat.h> 35 #include <sys/syscall.h> 36 #include <sys/resource.h> 37 #include <err.h> 38 39 #include "stress.h" 40 41 static char path[128]; 42 static int num; 43 static int starting_dir = 0; 44 45 static int ignore[] = { 46 SYS_syscall, 47 SYS_exit, 48 SYS_fork, 49 11, /* 11 is obsolete execv */ 50 SYS_unmount, 51 SYS_reboot, 52 SYS_vfork, 53 109, /* 109 is old sigblock */ 54 111, /* 111 is old sigsuspend */ 55 SYS_shutdown, 56 SYS___syscall, 57 SYS_rfork, 58 SYS_sigsuspend, 59 // SYS_mac_syscall, 60 SYS_sigtimedwait, 61 SYS_sigwaitinfo, 62 }; 63 64 int 65 setup(int nb) 66 { 67 int i; 68 struct rlimit rl; 69 70 umask(0); 71 sprintf(path,"%s.%05d", getprogname(), getpid()); 72 (void)mkdir(path, 0770); 73 if (chdir(path) == -1) 74 err(1, "chdir(%s), %s:%d", path, __FILE__, __LINE__); 75 if ((starting_dir = open(".", 0)) < 0) 76 err(1, "."); 77 78 if (op->argc == 1) { 79 num = atoi(op->argv[0]); 80 for (i = 0; i < sizeof(ignore) / sizeof(ignore[0]); i++) 81 if (num == ignore[i]) { 82 printf("syscall %d is marked a no test!\n", num); 83 exit(1); 84 } 85 } else { 86 num = 0; 87 while (num == 0) { 88 num = random_int(0, SYS_MAXSYSCALL); 89 for (i = 0; i < sizeof(ignore) / sizeof(ignore[0]); i++) 90 if (num == ignore[i]) { 91 num = 0; 92 break; 93 } 94 } 95 } 96 if (op->verbose > 1) 97 printf("Testing syscall #%d, pid %d\n", num, getpid()); 98 99 /* Multiple parallel core dump may panic the kernel with: 100 panic: kmem_malloc(184320): kmem_map too small: 84426752 total allocated 101 */ 102 rl.rlim_max = rl.rlim_cur = 0; 103 if (setrlimit(RLIMIT_CORE, &rl) == -1) 104 warn("setrlimit"); 105 106 setproctitle("#%d", num); 107 108 return (0); 109 } 110 111 void 112 cleanup(void) 113 { 114 if (starting_dir != 0) { 115 if (fchdir(starting_dir) == -1) 116 err(1, "fchdir()"); 117 (void)system("find . -type d -exec chmod 777 {} \\;"); 118 (void)system("find . -type f -exec chmod 666 {} \\;"); 119 (void)system("find . -delete"); 120 121 if (chdir("..") == -1) 122 err(1, "chdir(..)"); 123 if (rmdir(path) == -1) 124 err(1, "rmdir(%s), %s:%d", path, __FILE__, __LINE__); 125 } 126 starting_dir = 0; 127 } 128 129 int 130 test(void) 131 { 132 int i; 133 unsigned int arg1, arg2, arg3, arg4, arg5, arg6, arg7; 134 135 for (i = 0; i < 128; i++) { 136 arg1 = arc4random(); 137 arg2 = arc4random(); 138 arg3 = arc4random(); 139 arg4 = arc4random(); 140 arg5 = arc4random(); 141 arg6 = arc4random(); 142 arg7 = arc4random(); 143 144 if (op->verbose > 3) 145 printf("%2d : syscall(%3d, %x, %x, %x, %x, %x, %x, %x)\n", 146 i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); 147 syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); 148 } 149 #if 0 150 while (done_testing == 0) 151 sleep(1); 152 #endif 153 154 return (0); 155 } 156