-
Roland McGrath authored
There is a longstanding bug in the rt_sigreturn system call. This exists in both 2.4 and 2.6, and for almost every platform. I am referring to this code in sys_rt_sigreturn (arch/i386/kernel/signal.c): if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ /* * THIS CANNOT WORK! "&st" is a kernel address, and "do_sigaltstack()" * takes a user address (and verifies that it is a user address). End * result: it does exactly _nothing_. */ do_sigaltstack(&st, NULL, regs->esp); As the comment says, this is bogus. On vanilla i386 kernels, this is just harmlessly stupid--do_sigaltstack always does nothing and returns -EFAULT. However this code actually bites users on kernels using Ingo Molnar's 4G/4G address space layout changes. There some kernel stack address might very well be a lovely and readable user address as well. When that happens, we make a sigaltstack call with some random buffer, and then the fun begins. To my knowledge, this has produced trouble in the real world only for 4G i386 kernels (RHEL and Fedora "hugemem" kernels) on machines that actually have several GB of physical memory (and in programs that are actually using sigaltstack and handling a lot of signals). However, the same clearly broken code has been blindly copied to most other architecture ports, and off hand I don't know the address space details of any other well enough to know if real kernel stack addresses and real user addresses are in fact disjoint as they are on i386 when not using the nonstandard 4GB address space layout. The obvious intent of the call being there in the first place is to permit a signal handler to diddle its ucontext_t.uc_stack before returning, and have this effect a sigaltstack call on the signal handler return. This is not only an optimization vs doing the extra system call, but makes it possible to make a sigaltstack change when that handler itself was running on the signal stack. AFAICT this has never actually worked before, so certainly noone depends on it. But the code certainly suggests that someone intended at one time for that to be the behavior. Thus I am inclined to fix it so it works in that way, though it has not done so before. It would also be reasonable enough to simply rip out the bogus call and not have this functionality. From the current state of code in both 2.4 and 2.6, there is no fathoming how this broken code came about. It's actually much simpler to just make it work! I can only presume that at some point in the past the sigaltstack implementation functions were different such that this made sense. Of the few ports I've looked at briefly, only the ppc/pc64 porters (go paulus!) actually tried to understand what the i386 code was doing and implemented it correctly rather than just carefully transliterating the bug. The patch below fixes only the i386 and x86_64 versions. The x86_64 patches I have not actually tested. I think each and every arch (except ppc and ppc64) need to make the corresponding fixes as well. Note that there is a function to fix for each native arch, and then one for each emulation flavor. The details differ minutely for getting the calls right in each emulation flavor, but I think that most or all of the arch's with biarch/emulation support have similar enough code that each emulation flavor's fix will look very much like the arch/x86_64/ia32/ia32_signal.c patch here.
ce34221e