From 4e506f67cbe6cd935377da65909f0606014459aa Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Sat, 29 Apr 2023 23:18:19 +0300 Subject: hurd: Replace reply port with a dead name on failed interruption If we're trying to interrupt an interruptible RPC, but the server fails to respond to our __interrupt_operation () call, we instead destroy the reply port we were expecting the reply to the RPC on. Instead of deallocating the name completely, replace it with a dead name, so the name won't get reused for some other right, and deallocate it in _hurd_intr_rpc_mach_msg once we return from the signal handler. Signed-off-by: Sergey Bugaev Message-Id: <20230429201822.2605207-4-bugaevc@gmail.com> --- hurd/hurdsig.c | 15 ++++++++++++--- hurd/intr-msg.c | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'hurd') diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index b3808f9e49..78ea59d97d 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -477,9 +477,18 @@ _hurdsig_abort_rpcs (struct hurd_sigstate *ss, int signo, int sigthread, if (reply) { /* The interrupt didn't work. - Destroy the receive right the thread is blocked on. */ - __mach_port_destroy (__mach_task_self (), *reply); - *reply = MACH_PORT_NULL; + Destroy the receive right the thread is blocked on, and + replace it with a dead name to keep the name from reuse until + the therad is done with it. To do this atomically, first + insert a send right, and then destroy the receive right, + turning the send right into a dead name. */ + err = __mach_port_insert_right (__mach_task_self (), + *reply, *reply, + MACH_MSG_TYPE_MAKE_SEND); + assert_perror (err); + err = __mach_port_mod_refs (__mach_task_self (), *reply, + MACH_PORT_RIGHT_RECEIVE, -1); + assert_perror (err); } /* The system call return value register now contains diff --git a/hurd/intr-msg.c b/hurd/intr-msg.c index 1a086b5141..716d87ab6a 100644 --- a/hurd/intr-msg.c +++ b/hurd/intr-msg.c @@ -305,6 +305,7 @@ _hurd_intr_rpc_mach_msg (mach_msg_header_t *msg, { /* Make sure we have a valid reply port. The one we were using may have been destroyed by interruption. */ + __mig_dealloc_reply_port (rcv_name); m->header.msgh_local_port = rcv_name = __mig_get_reply_port (); m->header.msgh_bits = msgh_bits; option = user_option; -- cgit 1.4.1