From 13116fe93f18a06ae88f58103d034c997ccc8e77 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Wed, 18 Sep 2002 14:50:57 +0000 Subject: [PATCH] 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. MERGE TO ERASER git-svn-id: svn://svn.valgrind.org/valgrind/branches/VALGRIND_1_0_BRANCH@1074 --- vg_signals.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/vg_signals.c b/vg_signals.c index 27a4871e4f..39d365b621 100644 --- a/vg_signals.c +++ b/vg_signals.c @@ -874,13 +874,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; @@ -946,6 +963,7 @@ void vg_push_signal_frame ( ThreadId tid, int sigNo ) frame->retaddr = (UInt)(&VG_(signalreturn_bogusRA)); frame->sigNo = sigNo; + frame->sigNo_private = sigNo; frame->psigInfo = (Addr)NULL; frame->puContext = (Addr)NULL; frame->magicPI = 0x31415927; @@ -1035,7 +1053,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. */ -- 2.47.2