CPU Bug __DEATH__ Tester

Richard B. Johnson (root@chaos.analogic.com)
Fri, 14 Nov 1997 16:30:31 -0500 (EST)


The attached program has run for several hours on my Pentium-166 with
the F00F bug. I am still using version 2.1.63 but with the patches.

The exact same kernel, running on my Pentium-166 machine with SMP,
fails to fork() after a few minutes of operation. No, it does not
crash, memory doesn't disappear, zombies don't accumulate, it just
fails to fork. Attempts to execute commands from another task also
fail to fork. If I kill the parent with ^C, everything works fine again.

Cheers,
Dick Johnson

Richard B. Johnson
Project Engineer
Analogic Corporation
Penguin : Linux version 2.1.63 on an i586 machine (66.15 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

Program: <easier to delete here instead of attaching>

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <wait.h>
#include <signal.h>

struct itimerval t={{0x00000000,0x00000000},
{0x00000000,0x0002A000}};

unsigned char c[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc3};

void stopper(int unused)
{
exit(0xaa);
}

static pid_t pid;

void kill_kid(int unused)
{
kill(pid, SIGKILL);
}

void main(int unused, char *argv[])
{
int i, sig;
unsigned long *punch0, *punch1;
void(*f)() = (void *) c;
punch0 = (unsigned long *) c;
punch1 = (unsigned long *) &c[4];

strcpy(argv[0], "Parent");
for(;;)
{
*punch0 += (unsigned long) rand();
*punch1 += (unsigned long) rand();
switch((pid=fork()))
{
case 0:
strcpy(argv[0], "Kid (kill me)");
fprintf(stdout,"Trying %02X %02X %02X %02X %02X %02X %02X %02X %02X...",
c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8]);
fflush (stdout);
/*
* This stops any "forever" loops that may happen.
*/

#ifdef TEST_KID_KILLER
for(;;) ;
#endif
(void)signal(SIGQUIT, stopper);
(void)signal(SIGALRM, stopper);
(void)setitimer(ITIMER_REAL, &t, &t);
(*f)();
exit(0xbb);
break;
case -1:
fprintf(stderr, "Fork failed\n");
break;
default:
/*
* We will kill the child process in 1 second in case it trashes its
* own code and won't expire on its own.
*/
(void)signal(SIGALRM, kill_kid);
(void)alarm(1); /* Kill the kid in 1 second if it loops */
wait(&i); /* Wait for kid to die */
alarm(0); /* Remember to cancel the alarm */
sig = i & 0xff;
i >>= 0x08;
if(sig == SIGKILL)
fprintf(stdout, "killed by parent\n");
else if(i == 0xaa)
fprintf(stdout, "killed by timer\n");
else
fprintf(stdout, "normal exit\n");

fflush(stdout);
}
}
}