Messages in this thread Patch in this message | | | Date | Wed, 4 Feb 1998 11:39:50 -0800 (PST) | From | Linus Torvalds <> | Subject | Re: sigaction.sa_restorer problem / new signal handling / WINE |
| |
On Wed, 4 Feb 1998, Marcus Meissner wrote: > > While debugging a strange memorycorruption under WINE I noticed that the new > signal handling code seems to have changed the semantics of the (well, > obsolete, but neithertheless used by WINE) sigaction.sa_restorer field.
Ok, fixed, I think. Can some wine person test that my patch actually works for you?
Richard, the sa_restorer overloading is dangerous, maybe we should make sure that new-style signal handling uses a separate field after all?
Linus
----- --- v2.1.85/linux/arch/i386/kernel/signal.c Tue Dec 30 07:58:00 1997 +++ linux/arch/i386/kernel/signal.c Wed Feb 4 11:34:29 1998 @@ -365,21 +365,33 @@ /* non-iBCS2 extensions.. */ __put_user(mask, &sc->oldmask); __put_user(current->tss.cr2, &sc->cr2); -} +} + +/* + * Determine which stack to use.. + */ +static inline unsigned long sigstack_esp(struct k_sigaction *ka, struct pt_regs * regs) +{ + unsigned long esp; + + /* Default to using normal stack */ + esp = regs->esp; + + /* This is the legacy signal stack switching. */ + if ((regs->xss & 0xffff) != __USER_DS && + !(ka->sa.sa_flags & SA_RESTORER) && + ka->sa.sa_restorer) + esp = (unsigned long) ka->sa.sa_restorer; + + return esp; +} static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs) { struct sigframe *frame; - frame = (struct sigframe *)((regs->esp - sizeof(*frame)) & -8); - - /* XXX: Check here if we need to switch stacks.. */ - - /* This is legacy signal stack switching. */ - if ((regs->xss & 0xffff) != __USER_DS - && !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer) - frame = (struct sigframe *) ka->sa.sa_restorer; + frame = (struct sigframe *)((sigstack_esp(ka, regs) - sizeof(*frame)) & -8); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto segv_and_exit; @@ -441,14 +453,7 @@ { struct rt_sigframe *frame; - frame = (struct rt_sigframe *)((regs->esp - sizeof(*frame)) & -8); - - /* XXX: Check here if we need to switch stacks.. */ - - /* This is legacy signal stack switching. */ - if ((regs->xss & 0xffff) != __USER_DS - && !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer) - frame = (struct rt_sigframe *) ka->sa.sa_restorer; + frame = (struct rt_sigframe *)((sigstack_esp(ka, regs) - sizeof(*frame)) & -8); if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto segv_and_exit;
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |