Subject: port-i386/944: LDT manipulation can hard-hang an i386 system
To: None <gnats-admin@NetBSD.ORG>
From: John Kohl <jtk@kolvir.blrc.ma.us>
List: netbsd-bugs
Date: 04/06/1995 21:35:04
>Number: 944
>Category: port-i386
>Synopsis: LDT manipulation of LDTEs for segs 0x17 can hard-hang an i386 system
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Apr 6 21:35:03 1995
>Originator: John Kohl
>Organization:
NetBSD Kernel Hackers `R` Us
>Release: -current
>Environment:
System: NetBSD kolvir 1.0A NetBSD 1.0A (KOLVIR) #187: Thu Apr 6 22:52:57 EDT 1995 jtk@kolvir:/u1/NetBSD-current/src/sys/arch/i386/compile/KOLVIR i386
>Description:
In a kernel with USER_LDT enabled, a user can hang the system hard (ddb
can't get control on the console--reset button needed).
>How-To-Repeat:
Run this program. When the program replaces its LDT entry for
its code segment (corresponding to %cs = 0x1f), it will get a SIGBUS
upon return to user space because the code segment descriptor will be of
type SDT_SYSNULL. The kernel tries to deliver SIGBUS, and sets %cs to
0x1f. The signal is started, it takes another SIGBUS, and something bad
happens (not sure what) that locks up the processor completely.
#include <signal.h>
#include <sys/types.h>
#include <machine/segments.h>
#include <machine/sysarch.h>
sigbus(int sig, int code, struct sigcontext *scp)
{
printf("sigbus\n");
abort();
exit(1);
}
main()
{
int ldte[2];
register int i;
register int rval;
signal(SIGBUS,sigbus);
for (i = 0; i < 8192; i++) {
ldte[0] = 0;
ldte[1] = 0xe000; /* present, DPL = 3 */
rval = i386_set_ldt(i, (union descriptor *)ldte, 1);
printf("entry %d: %d\n", i, rval);
sleep(1);
}
exit(0);
}
>Fix:
>Audit-Trail:
>Unformatted: