aboutsummaryrefslogtreecommitdiff
path: root/hurd
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@gmail.com>2023-04-29 23:18:19 +0300
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-05-01 03:18:48 +0200
commit4e506f67cbe6cd935377da65909f0606014459aa (patch)
treeaa701a83abdd2769c5ee3067cd048646af39ea22 /hurd
parenteb14819c14d190830df673c9a3089d82d6b7b8f7 (diff)
downloadglibc-4e506f67cbe6cd935377da65909f0606014459aa.zip
glibc-4e506f67cbe6cd935377da65909f0606014459aa.tar.gz
glibc-4e506f67cbe6cd935377da65909f0606014459aa.tar.bz2
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 <bugaevc@gmail.com> Message-Id: <20230429201822.2605207-4-bugaevc@gmail.com>
Diffstat (limited to 'hurd')
-rw-r--r--hurd/hurdsig.c15
-rw-r--r--hurd/intr-msg.c1
2 files changed, 13 insertions, 3 deletions
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index b3808f9..78ea59d 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 1a086b5..716d87a 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;