One interesting thing I notice about the Linux 2.0.33 kernel spewing out it's #GP(0) error message, is that pretty much all registers are reported incorrectly. All values are seemingly garbled up(all segments and data register but SS:ESP are reported with incorrect values. When the exception handler is thrown, most data registers have value 0x18 in them, CS 0x10, SS is correctly reported). Even CS:EIP is reported incorrectly(CS is definitely 0x10(:1E3439), while EIP is a completely different value, both being reported incorrectly).
Edit: Just found a bug that caused RET[D] to add the immediate number to the stack, even when a fault was raised(in the case of a fault, it would add to the exception handler's stack incorrectly, destroying anything pushed there(depending on the immediate value).
No effect on this, though, since RET has an (hardcoded) immediate of 0(since it doesn't add anything to the stack). But it still reports all registers incorrectly?
The location data pushed on the stack during the invalid RET:
205702=EFLAGS
CS=0010
EIP=1E3439
EIP of the error handler(#GP) becomes 10AA6C
The error code pushed is 0.
Edit: The RET seems to also be called a RETN instruction(opcode C3). The stack seems like it's loaded, but the value that's popped off is completely invalid(it's in user memory instead of kernel memory). Also, CS.base is C0000000 and limit 3FFFFFFF. So the return address must be 100% invalid.