xref: /minix3/minix/tests/test62.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1 /* FPU state corruption test. This used to be able to crash the kernel. */
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <signal.h>
6 #include <sys/wait.h>
7 #include <machine/fpu.h>
8 
9 int max_error = 1;
10 #include "common.h"
11 
12 
13 double state = 2.0;
14 static int count;
15 
use_fpu(int n)16 static void use_fpu(int n)
17 {
18   state += (double) n * 0.5;
19 }
20 
crashed(int sig)21 static void crashed(int sig)
22 {
23   exit(EXIT_SUCCESS);
24 }
25 
handler(int sig,int code,struct sigcontext * sc)26 static void handler(int sig, int code, struct sigcontext *sc)
27 {
28   memset(&sc->sc_fpu_state, count, sizeof(sc->sc_fpu_state));
29 }
30 
main(void)31 int main(void)
32 {
33   int status;
34 
35   start(62);
36   subtest = 0;
37 
38   signal(SIGUSR1, (void (*)(int)) handler);
39 
40   /* Initialize the FPU state. This state is inherited, too. */
41   use_fpu(-1);
42 
43   for (count = 0; count <= 255; count++) {
44 	switch (fork()) {
45 	case -1:
46 		e(1);
47 
48 		break;
49 
50 	case 0:
51 		signal(SIGFPE, crashed);
52 
53 		/* Load bad state into the kernel. */
54 		if (kill(getpid(), SIGUSR1)) e(2);
55 
56 		/* Let the kernel restore the state. */
57 		use_fpu(count);
58 
59 		exit(EXIT_SUCCESS);
60 
61 	default:
62 		/* We cannot tell exactly whether what happened is correct or
63 		 * not -- certainly not in a platform-independent way. However,
64 		 * if the whole system keeps running, that's good enough.
65 		 */
66 		(void) wait(&status);
67 	}
68   }
69 
70   if (state <= 1.4 || state >= 1.6) e(3);
71 
72   quit();
73 
74   return 0;
75 }
76