Re: Repeatable kernel crash [2.1.55, Wine, Control Panel]

Morten Welinder (terra@diku.dk)
Tue, 7 Oct 1997 01:40:54 +0200


Thanks to Marcus Meissner for pointing out the culprit: modify_ldt
(and not old_select as I suspected as it was the last thing I saw).

The following program locks up Linux for me. Don't run this unless
you have mounted your disks read-only. Note that without the final
sleep(1), the crash doesn't seem to happen.

Morten

/* whack-a-penguin.c */
#include <asm/ldt.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

static int
modify_ldt (int func, struct modify_ldt_ldt_s *ptr, size_t count)
{
int res;
__asm__ __volatile__( "pushl %%ebx\n\t"
"movl %2,%%ebx\n\t"
"int $0x80\n\t"
"popl %%ebx"
: "=a" (res)
: "0" (SYS_modify_ldt),
"g" (func),
"c" (ptr),
"d" (count) );
if (res >= 0) return res;
errno = -res;
return -1;
}

int
main ()
{
struct modify_ldt_ldt_s foo;
int sel = 7;
int i;

foo.entry_number = sel / 8;
foo.base_addr = (unsigned long)&main;
foo.limit = 1;
foo.seg_32bit = 1;
foo.contents = 0;
foo.read_exec_only = 0;
foo.limit_in_pages = 0;
foo.seg_not_present = 0;
if (modify_ldt (1, &foo, sizeof (foo)))
perror ("modify_ldt");

__asm__ __volatile__ ("movw %w0,%%fs"::"r" (sel));
__asm__ __volatile__ ("movw %w0,%%gs"::"r" (sel));

for (i = 10; i > 0; i--)
{
printf ("%d...\n", i);
sync ();
sleep (1);
}

memset (&foo, 0, sizeof (foo));
if (modify_ldt (1, &foo, sizeof (foo)))
perror ("modify_ldt");
sleep (1);
printf ("OK.\n");

return 0;
}