]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
merge rev 1.29.2.3:
authorJulian Seward <jseward@acm.org>
Fri, 27 Sep 2002 00:46:59 +0000 (00:46 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 27 Sep 2002 00:46:59 +0000 (00:46 +0000)
Fix stupid bug in which vg_push_signal_frame/vg_pop_signal_frame assumed
that the handler wouldn't change the signal-number parameter it was passed.

Fixes this:
   vg_signals.c:1065 (vgPlain_signal_returns):
   Assertion `sigNo >= 1 && sigNo <= 64' failed.
and possibly arbitrary other mutancy in the signal handling too.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1111

coregrind/vg_signals.c

index f849544012e00ee610b8f191c45c39a27e807574..4b72ae807930b34ed8693e94a584bd62019f2945 100644 (file)
@@ -875,13 +875,30 @@ void VG_(restore_all_host_signals) ( /* IN */ vki_ksigset_t* saved_mask )
 
 typedef
    struct {
-      /* These are parameters to the signal handler. */
-      UInt retaddr;   /* Sig handler's (bogus) return address */
-      Int  sigNo;     /* The arg to the sig handler.  */
-      Addr psigInfo;  /* ptr to siginfo_t; NULL for now. */
-      Addr puContext; /* ptr to ucontext; NULL for now. */
+      /* These 4 are parameters to the signal handler.  The order of
+         them is important, since this whole struct is pushed onto the
+         client's stack at delivery time.  The first 4 words -- which
+         will be at the top of the stack -- constitute 4 arg words to
+         the handler. */
+
+      /* Sig handler's (bogus) return address */
+      Addr retaddr;
+      /* The arg to the sig handler.  We need to inspect this after
+         the handler returns, but it's unreasonable to assume that the
+         handler won't change it.  So we keep a second copy of it in
+         sigNo_private. */
+      Int  sigNo;
+      /* ptr to siginfo_t; NULL for now. */
+      Addr psigInfo;
+      /* ptr to ucontext; NULL for now. */
+      Addr puContext;
+
+      /* The rest are private fields which the handler is unaware of. */
+
       /* Sanity check word. */
       UInt magicPI;
+      /* Safely-saved version of sigNo, as described above. */
+      Int  sigNo_private;
       /* Saved processor state. */
       UInt fpustate[VG_SIZE_OF_FPUSTATE_W];
       UInt eax;
@@ -955,6 +972,7 @@ void vg_push_signal_frame ( ThreadId tid, int sigNo )
                             (Addr)esp, 16 );
    frame->retaddr    = (UInt)(&VG_(signalreturn_bogusRA));
    frame->sigNo      = sigNo;
+   frame->sigNo_private = sigNo;
    frame->psigInfo   = (Addr)NULL;
    frame->puContext  = (Addr)NULL;
    frame->magicPI    = 0x31415927;
@@ -1038,7 +1056,10 @@ Int vg_pop_signal_frame ( ThreadId tid )
    tst->m_edi     = frame->edi;
    tst->m_eflags  = frame->eflags;
    tst->m_eip     = frame->eip;
-   sigNo          = frame->sigNo;
+
+   /* don't use the copy exposed to the handler; it might have changed
+      it. */
+   sigNo          = frame->sigNo_private; 
 
    /* And restore the thread's status to what it was before the signal
       was delivered. */