Messages in this thread | | | Date | Tue, 25 Aug 1998 02:22:35 +0100 | From | Jamie Lokier <> | Subject | Re: copy_from_user() fix |
| |
On Tue, Aug 25, 1998 at 01:45:12AM +0100, Jamie Lokier wrote: > Will I don't agree with the feature either, all we're talking about is > adding one line to the page fault handler: send_sig(SIGSEGV). Nothing > else needs to change, does it?
I just changed my mind.
I bet no applications at all currently check for EFAULT from system calls, unless they're really weird and are doing it to behave _as if_ they'd received SIGSEGV. Actually I bet they don't bother because every syscall would need to be wrapped. I'm theorising that this could screw up Wine in some unusual but valid cases.
To make matters worse, if they do this by calling the signal handler directly, the faulting address isn't available. If they do kill (getpid(),SIGSEGV), a fault may have happened in the mean time so the faulting address may be wrong or lost. In the latter case, as luck would have it, probably the operations retry until the right address is found. But it is a matter of luck, and anything that tried to count faults could get it wrong in these rare cases.
So...
- EFAULT alone is an anachronism. - Only a few applications care whether SIGSEGV is raised or not. - Some emulators and user-space page management depend on SIGSEGV for page faults, and will behave incorrectly when it is not raised in syscalls. - There is no correct workaround other than the kernel raising SIGSEGV.
I propose EFAULT should be retained, but faulting syscalls should _also_ raise SIGSEGV.
Addendum for a related problem: Consider when a syscall, interrupt etc. (whatever) combination manage to raise more than one signal _at the same time_, of which one is SIGSEGV due to a page fault. Assume the program is using user-space page management for something.
A handler for one of the other signals is called first. The handler may itself fault, causing a SIGSEGV if it is not blocked. Or perhaps storing the context on the stack might fault. A nested call to the SEGV handler handles the inner fault. The other handler returns, then a context the SIGSEGV handler is called for the original fault. Now, the page fault address from %cr2 (or non-Intel equivalent) is stored in the context passed to the handler. But it is wrong by now! It is the address of the inner fault, which has already been handled.
Ho hum.
Perhaps a VM extension could be written, whereby page faults send a queued real-time signal along with the faulting address, and maybe some information to identify the faulting region too. That would work properly because the address can be queued at the time of the fault.
-- Jamie
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html
| |