Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Dec 2003 11:27:26 -0800
From:      "Luoqi Chen" <lchen@briontech.com>
To:        "Matthew Dillon" <dillon@apollo.backplane.com>, <stable@freebsd.org>
Subject:   RE: Bug in i386/i386/trap.c %gs handling on stable
Message-ID:  <AHEKICEOIHLOGINAFIINCEGMCBAA.lchen@briontech.com>
In-Reply-To: <200312070413.hB74Dm7g058674@apollo.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
> 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. 
> 
I don't quite get it. There'll be fault only when the kernel tries to
load an invalid %gs. And there's only one place that the kernel would
load a new %gs: during a context switch, which could not take place in
an interrupt context.

> 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.
>
It's different for %fs, it holds a valid kernel segment at all time
inside the kernel.
 
> 
>     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);
> 
>

-lq 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AHEKICEOIHLOGINAFIINCEGMCBAA.lchen>