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
tobemangled(void)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
mangle(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
hand(int i __unused)65 hand(int i __unused) { /* handler */
66 _exit(1);
67 }
68
69 static void
ahand(int i __unused)70 ahand(int i __unused) { /* alarm handler */
71 if (pid != 0) {
72 kill(pid, SIGKILL);
73 }
74 _exit(EXIT_SUCCESS);
75 }
76
77 int
setup(int nb __unused)78 setup(int nb __unused)
79 {
80 return (0);
81 }
82
83 void
cleanup(void)84 cleanup(void)
85 {
86 }
87
88 int
test(void)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