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 16 static void use_fpu(int n) 17 { 18 state += (double) n * 0.5; 19 } 20 21 static void crashed(int sig) 22 { 23 exit(EXIT_SUCCESS); 24 } 25 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 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