In addition to the concerns I posted on bugtraq regarding handling of
INTO and BOUND instructions, and the (albeit minor) differences in
handling INT $0, INT $1, INT $2, and INT $6 from user code, the new
revision of the BSDI patch fails in two additional ways:
It directly accesses a linear address in user space using the kernel
segment descriptors, ignoring that the process may be in VM86 mode or
16-bit protected mode. (You might be able to ignore protected mode if
you don't allow the user to create segment descriptors. We do to
support WINE and WABI.) Not only will it therefore get the PC (%eip)
fixup wrong in these modes, but it may also cause an unhandled page
fault in kernel space, which will cause the kernel to crash. This is
highly suboptimal.
If you're going to look at the user instruction (which you *need* to
do to properly handle BOUND), then you must do the segment
translations correctly. Note that there's a race condition here in
SMP systems, but in practice this is minor; if the user changes the
instruction while we're doing the fixup, the fixup will do something
not quite right, but should not create a security hole.
I include below three pieces of mail from me about this on bugtraq.
(Note that my suggested way of reexecuting the instruction actually
can't work correctly in a SMP system, but I include it here for
completeness. Basically, the user could change the instruction before
it's reexecuted to be something that doesn't trap, then do a bunch of
things to cause the cache to be completely flushed, and do the hanging
instruction again while we're still pointing to the fully mapped IDT,
causing the hang. We could try to work around this using the trace
flag to force an exception, but in protected mode the user can change
the trace flag.)
[Other messages omitted, since I already sent them here.]