Re: copy_from_user() fix

Richard Gooch (rgooch@atnf.csiro.au)
Tue, 25 Aug 1998 14:29:28 +1000


Jamie Lokier writes:
> 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.

Well, you're wrong. I do have applications that explicitely check for
EFAULT. I *don't* want them to receive SEGV.

> 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.

Only if raising SEGV is *optional* and by default disabled. Existing
behaviour should not and need not be changed.

> 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.

Checking for EFAULT seems to solve these problems you are introducing
by rasing SEGV in the first place.

Regards,

Richard....

-
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