bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

hurd: Fix longjmp from signal handler


From: Samuel Thibault
Subject: hurd: Fix longjmp from signal handler
Date: Tue, 20 Oct 2015 22:24:12 +0200
User-agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30)

Hello,

The patch below fixes a corner case of signals: when longjumping from a
signal handler, the code currently restores the reply port used by the
main code.  But since we possibly longjmp over a pending RPC, we should
rather just kill that reply port, which will thus get recreated on next
RPC.  Otherwise, the next RPC will try to use it and probably receive a
message that was for the interrupted RPC, and thus produce a -301 error
(EMIG_REPLY_MISMATCH)... For instance, the testcase below always show
that mach_port_destroy returns a -301 error: it actually gets the reply
message of the raise call itself...

Roland, do you agree on this?

Samuel


#include <mach.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <setjmp.h>

jmp_buf jb;

void handle(int sig) {
        fprintf(stderr, "got it\n");
        siglongjmp(jb, sig);
}

int main(void) 
{
        int res;
        int i;
        int err = 0;
        signal(SIGBUS, handle);

        if (!(res = sigsetjmp(jb, 1)))
        {
                res = raise(SIGBUS);
                if (res)
                        perror("raise");
        }
        else
        {
                res = mach_port_destroy(__mach_task_self(), MACH_PORT_NULL);
                if (res)
                        fprintf(stderr,"%d\n", res);
        }
        return 0;
}


diff --git a/hurd/sigunwind.c b/hurd/sigunwind.c
index 3a62fb5..e535c4a 100644
--- a/hurd/sigunwind.c
+++ b/hurd/sigunwind.c
@@ -50,7 +50,8 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int 
val)
          *reply_port = MACH_PORT_DEAD;
          __mach_port_destroy (__mach_task_self (), port);
        }
-      *reply_port = scp->sc_reply_port;
+      if (scp->sc_reply_port)
+       __mach_port_destroy (__mach_task_self (), scp->sc_reply_port);
     }
 
   __spin_lock (&ss->lock);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]