Bug in i386/i386/trap.c %gs handling on stable

Matthew Dillon dillon at apollo.backplane.com
Sat Dec 6 20:13:49 PST 2003


In i386/i386/trap.c if %gs is invalid... for example, a process with a 
USER_LDT takes an interrupt while exiting, or if %gs is set through procfs,
the fault check must occur regardless of the interrupt nesting level because
mainline code does not push and load a %gs for the kernel. 

FreeBSD-5.x has already moved this check to outside the nesting level test.

It may also be possible that %fs can cause the same problem to occur in
the situation with a process takes an interrupt while exiting and %fs is
set to a USER_LDT entry.  I have not checked this, but if it is true it would
be a problem in both -current and -stable for the exiting case.


    if (intr_nesting_level == 0) {
	    /*
	     * Invalid %fs's and %gs's can be created using
	     * procfs or PT_SETREGS or by invalidating the
	     * underlying LDT entry.  This causes a fault
	     * in kernel mode when the kernel attempts to
	     * switch contexts.  Lose the bad context
	     * (XXX) so that we can continue, and generate
	     * a signal.
	     */
	    if (frame.tf_eip == (int)cpu_switch_load_gs) {   	<<< WRONG
		    curpcb->pcb_gs = 0;   			<<<
		    psignal(p, SIGBUS);				<<<
		    return;					<<<
	    }
	    MAYBE_DORETI_FAULT(doreti_iret,
			       doreti_iret_fault);





More information about the freebsd-stable mailing list