Messages in this thread |  | | Subject | PATCH for 2.1.26: newly forked processes killed by "handled signals" | From | (Kevin Buhr) | Date | 12 Feb 1997 23:24:48 -0600 |
| |
Alan:
After your patch fixed the "socketpair" behaviour, I got "dump" working and managed to discover another 2.1.26 kernel bug. The changes to "sys_sigreturn" in "arch/i386/kernel/signal.c" that added more rigorous checking of segment register values---I don't know when they were added---have the unintended side effect of causing crashes in certain very rare circumstances.
Basically, the "copy_thread" function of "arch/i386/kernel/signal.c" initializes the TSS's %gs with KERNEL_DS. If the newly forked child is signaled immediately *and* if the child has a handler for that signal, then the pseudobogus %gs value will be saved by "setup_frame" (in "arch/i386/kernel/signal.c") and, when returning from the handler, the "GET_SEG(gs)" in "sys_sigreturn" will barf and "do_exit(SIGSEGV)" the child.
For reasons I still don't fully understand, if the child is allowed to return from the "fork" call and begin execution before receiving the signal, the %gs register is automagically "fixed" (but I can't figure out where), and we never notice the problem. The enclosed "signaltest.c" illustrates the bug: on a vanilla 2.1.26 kernel, the child quiety dies immediately after handling the signal. A hacked up kernel verifies that "GET_SEG(gs)" is the culprit.
The enclosed patch appears to fix the problem by having "copy_thread" initialize %gs with "USER_DS" instead, as is done in other, similar contexts. Does this break anything else?
Kevin <buhr@stat.wisc.edu> [unhandled content-type:application/octet-stream][unhandled content-type:application/octet-stream] |  |