1 /* 2 * COPYRIGHT (c) 1990 BY * 3 * GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS. * 4 * ALL RIGHTS RESERVED * 5 6 Permission to use, copy, modify, distribute and sell this software 7 and its documentation for any purpose and without fee is hereby 8 granted, provided that the above copyright notice appear in all copies 9 and that both that copyright notice and this permission notice appear 10 in supporting documentation, and that the name of the author 11 not be used in advertising or publicity pertaining to distribution 12 of the software without specific, written prior permission. 13 14 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 15 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 16 HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 17 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 18 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 19 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 SOFTWARE. 21 22 This code is based on crashme.c 23 24 */ 25 26 #include <sys/types.h> 27 #include <sys/mman.h> 28 #include <sys/param.h> 29 #include <sys/resource.h> 30 #include <sys/time.h> 31 #include <err.h> 32 #include <signal.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <sys/wait.h> 36 #include <unistd.h> 37 38 #include "stress.h" 39 40 static pid_t pid; 41 static int failsafe; 42 43 static int 44 tobemangled(void) { 45 volatile int i, j; 46 47 j = 2; 48 for (i = 0; i < 100; i++) 49 j = j + 3; 50 j = j / 2; 51 52 return (j); 53 } 54 55 static void 56 mangle(void) { /* Change one byte in the code */ 57 int i; 58 char *p = (void *)tobemangled; 59 60 i = arc4random() % 50; 61 p[i] = arc4random() & 0xff; 62 } 63 64 static void 65 hand(int i __unused) { /* handler */ 66 _exit(1); 67 } 68 69 static void 70 ahand(int i __unused) { /* alarm handler */ 71 if (pid != 0) { 72 kill(pid, SIGKILL); 73 } 74 _exit(EXIT_SUCCESS); 75 } 76 77 int 78 setup(int nb __unused) 79 { 80 return (0); 81 } 82 83 void 84 cleanup(void) 85 { 86 } 87 88 int 89 test(void) 90 { 91 void *st; 92 struct rlimit rl; 93 94 if (failsafe) 95 return (0); 96 97 while (done_testing == 0) { 98 signal(SIGALRM, ahand); 99 alarm(3); 100 if ((pid = fork()) == 0) { 101 rl.rlim_max = rl.rlim_cur = 0; 102 if (setrlimit(RLIMIT_CORE, &rl) == -1) 103 warn("setrlimit"); 104 st = (void *)trunc_page((unsigned long)tobemangled); 105 if (mprotect(st, PAGE_SIZE, PROT_WRITE | PROT_READ | 106 PROT_EXEC) == -1) 107 err(1, "mprotect()"); 108 109 signal(SIGALRM, hand); 110 signal(SIGILL, hand); 111 signal(SIGFPE, hand); 112 signal(SIGSEGV, hand); 113 signal(SIGBUS, hand); 114 signal(SIGURG, hand); 115 signal(SIGSYS, hand); 116 signal(SIGTRAP, hand); 117 118 mangle(); 119 failsafe = 1; 120 (void)tobemangled(); 121 122 _exit(EXIT_SUCCESS); 123 124 } else if (pid > 0) { 125 if (waitpid(pid, NULL, 0) == -1) 126 warn("waitpid(%d)", pid); 127 alarm(0); 128 } else 129 err(1, "fork(), %s:%d", __FILE__, __LINE__); 130 } 131 132 return (0); 133 } 134