18a272653SPeter Holm /*
28a272653SPeter Holm  *             COPYRIGHT (c) 1990 BY             *
38a272653SPeter Holm  *  GEORGE J. CARRETTE, CONCORD, MASSACHUSETTS.  *
48a272653SPeter Holm  *             ALL RIGHTS RESERVED               *
58a272653SPeter Holm 
68a272653SPeter Holm Permission to use, copy, modify, distribute and sell this software
78a272653SPeter Holm and its documentation for any purpose and without fee is hereby
88a272653SPeter Holm granted, provided that the above copyright notice appear in all copies
98a272653SPeter Holm and that both that copyright notice and this permission notice appear
108a272653SPeter Holm in supporting documentation, and that the name of the author
118a272653SPeter Holm not be used in advertising or publicity pertaining to distribution
128a272653SPeter Holm of the software without specific, written prior permission.
138a272653SPeter Holm 
148a272653SPeter Holm THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
158a272653SPeter Holm ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
168a272653SPeter Holm HE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
178a272653SPeter Holm ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
188a272653SPeter Holm WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
198a272653SPeter Holm ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
208a272653SPeter Holm SOFTWARE.
218a272653SPeter Holm 
228a272653SPeter Holm This code is based on crashme.c
238a272653SPeter Holm 
248a272653SPeter Holm */
258a272653SPeter Holm 
268a272653SPeter Holm #include <sys/types.h>
278a272653SPeter Holm #include <sys/mman.h>
288a272653SPeter Holm #include <sys/param.h>
298a272653SPeter Holm #include <sys/resource.h>
308a272653SPeter Holm #include <sys/time.h>
318a272653SPeter Holm #include <err.h>
328a272653SPeter Holm #include <signal.h>
338a272653SPeter Holm #include <stdio.h>
348a272653SPeter Holm #include <stdlib.h>
358a272653SPeter Holm #include <sys/wait.h>
368a272653SPeter Holm #include <unistd.h>
378a272653SPeter Holm 
388a272653SPeter Holm #include "stress.h"
398a272653SPeter Holm 
408a272653SPeter Holm static pid_t pid;
418a272653SPeter Holm static int failsafe;
428a272653SPeter Holm 
438a272653SPeter Holm static int
tobemangled(void)448a272653SPeter Holm tobemangled(void) {
458a272653SPeter Holm 	volatile int i, j;
468a272653SPeter Holm 
478a272653SPeter Holm 	j = 2;
488a272653SPeter Holm 	for (i = 0; i < 100; i++)
498a272653SPeter Holm 		j = j + 3;
508a272653SPeter Holm 	j = j / 2;
518a272653SPeter Holm 
528a272653SPeter Holm 	return (j);
538a272653SPeter Holm }
548a272653SPeter Holm 
558a272653SPeter Holm static void
mangle(void)568a272653SPeter Holm mangle(void) {	/* Change one byte in the code */
578a272653SPeter Holm 	int i;
588a272653SPeter Holm 	char *p = (void *)tobemangled;
598a272653SPeter Holm 
608a272653SPeter Holm 	i = arc4random() % 50;
618a272653SPeter Holm 	p[i] = arc4random() & 0xff;
628a272653SPeter Holm }
638a272653SPeter Holm 
648a272653SPeter Holm static void
hand(int i __unused)658a272653SPeter Holm hand(int i __unused) {	/* handler */
668a272653SPeter Holm 	_exit(1);
678a272653SPeter Holm }
688a272653SPeter Holm 
698a272653SPeter Holm static void
ahand(int i __unused)708a272653SPeter Holm ahand(int i __unused) {	/* alarm handler */
718a272653SPeter Holm 	if (pid != 0) {
728a272653SPeter Holm 		kill(pid, SIGKILL);
738a272653SPeter Holm 	}
748a272653SPeter Holm 	_exit(EXIT_SUCCESS);
758a272653SPeter Holm }
768a272653SPeter Holm 
778a272653SPeter Holm int
setup(int nb __unused)788a272653SPeter Holm setup(int nb __unused)
798a272653SPeter Holm {
808a272653SPeter Holm 	return (0);
818a272653SPeter Holm }
828a272653SPeter Holm 
838a272653SPeter Holm void
cleanup(void)848a272653SPeter Holm cleanup(void)
858a272653SPeter Holm {
868a272653SPeter Holm }
878a272653SPeter Holm 
888a272653SPeter Holm int
test(void)898a272653SPeter Holm test(void)
908a272653SPeter Holm {
918a272653SPeter Holm 	void *st;
928a272653SPeter Holm 	struct rlimit rl;
938a272653SPeter Holm 
948a272653SPeter Holm 	if (failsafe)
958a272653SPeter Holm 		return (0);
968a272653SPeter Holm 
978a272653SPeter Holm 	while (done_testing == 0) {
988a272653SPeter Holm 		signal(SIGALRM, ahand);
998a272653SPeter Holm 		alarm(3);
1008a272653SPeter Holm 		if ((pid = fork()) == 0) {
1018a272653SPeter Holm 			rl.rlim_max = rl.rlim_cur = 0;
1028a272653SPeter Holm 			if (setrlimit(RLIMIT_CORE, &rl) == -1)
1038a272653SPeter Holm 				warn("setrlimit");
1048a272653SPeter Holm 			st = (void *)trunc_page((unsigned long)tobemangled);
1058a272653SPeter Holm 			if (mprotect(st, PAGE_SIZE, PROT_WRITE | PROT_READ |
1068a272653SPeter Holm 			    PROT_EXEC) == -1)
1078a272653SPeter Holm 				err(1, "mprotect()");
1088a272653SPeter Holm 
1098a272653SPeter Holm 			signal(SIGALRM, hand);
1108a272653SPeter Holm 			signal(SIGILL,  hand);
1118a272653SPeter Holm 			signal(SIGFPE,  hand);
1128a272653SPeter Holm 			signal(SIGSEGV, hand);
1138a272653SPeter Holm 			signal(SIGBUS,  hand);
1148a272653SPeter Holm 			signal(SIGURG,  hand);
1158a272653SPeter Holm 			signal(SIGSYS,  hand);
1168a272653SPeter Holm 			signal(SIGTRAP, hand);
1178a272653SPeter Holm 
1188a272653SPeter Holm 			mangle();
1198a272653SPeter Holm 			failsafe = 1;
1208a272653SPeter Holm 			(void)tobemangled();
1218a272653SPeter Holm 
1228a272653SPeter Holm 			_exit(EXIT_SUCCESS);
1238a272653SPeter Holm 
1248a272653SPeter Holm 		} else if (pid > 0) {
1258a272653SPeter Holm 			if (waitpid(pid, NULL, 0) == -1)
1268a272653SPeter Holm 				warn("waitpid(%d)", pid);
1278a272653SPeter Holm 			alarm(0);
1288a272653SPeter Holm 		} else
1298a272653SPeter Holm 			err(1, "fork(), %s:%d",  __FILE__, __LINE__);
1308a272653SPeter Holm 	}
1318a272653SPeter Holm 
1328a272653SPeter Holm 	return (0);
1338a272653SPeter Holm }
134