[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH v3 3/6] hurd: Replace reply port with a dead name on fail
From: |
Samuel Thibault |
Subject: |
Re: [RFC PATCH v3 3/6] hurd: Replace reply port with a dead name on failed interruption |
Date: |
Mon, 1 May 2023 03:20:22 +0200 |
User-agent: |
NeoMutt/20170609 (1.8.3) |
Applied, thanks!
Sergey Bugaev, le sam. 29 avril 2023 23:18:19 +0300, a ecrit:
> 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>
> ---
> This is not required for x86_64, but probably a good idea anyway. I have
> checked that this does not fatally break things (this commit has been
> sitting in my tree, getting built along with the other changes, for quite
> some time without noticably breaking anything), but I have not run the
> full testsuite. Please do that on your end.
>
> hurd/hurdsig.c | 15 ++++++++++++---
> hurd/intr-msg.c | 1 +
> sysdeps/mach/hurd/mig-reply.c | 25 +++++++------------------
> 3 files changed, 20 insertions(+), 21 deletions(-)
>
> diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
> index b3808f9e..78ea59d9 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 1a086b51..716d87ab 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;
> diff --git a/sysdeps/mach/hurd/mig-reply.c b/sysdeps/mach/hurd/mig-reply.c
> index 3fdee80e..7ea001df 100644
> --- a/sysdeps/mach/hurd/mig-reply.c
> +++ b/sysdeps/mach/hurd/mig-reply.c
> @@ -69,29 +69,18 @@ __mig_dealloc_reply_port (mach_port_t arg)
> mach_port_t port = get_reply_port ();
>
> set_reply_port (MACH_PORT_NULL); /* So the mod_refs RPC won't use it. */
> -
> - /* Normally, ARG should be the same as PORT that we store. However, if a
> - signal has interrupted the RPC, the stored PORT has been deallocated and
> - reset to MACH_PORT_NULL (or possibly MACH_PORT_DEAD). In this case the
> - MIG routine still has the old name, which it passes to us here. We must
> - not deallocate (or otherwise touch) it, since it may be already
> allocated
> - to another port right. Fortunately MIG itself doesn't do anything with
> - the reply port on errors either, other than immediately calling this
> - function.
> -
> - And so:
> - 1. Assert that things are sane, i.e. and PORT is either invalid or same
> - as ARG.
> - 2. Only deallocate the name if our stored PORT still names it. In that
> - case we're sure the right has not been deallocated / the name reused.
> - */
> -
> + assert (port == arg);
> if (!MACH_PORT_VALID (port))
> return;
> - assert (port == arg);
>
> err = __mach_port_mod_refs (__mach_task_self (), port,
> MACH_PORT_RIGHT_RECEIVE, -1);
> + if (err == KERN_INVALID_RIGHT)
> + /* It could be that during signal handling, the receive right had been
> + replaced with a dead name. */
> + err = __mach_port_mod_refs (__mach_task_self (), port,
> + MACH_PORT_RIGHT_DEAD_NAME, -1);
> +
> assert_perror (err);
> }
> weak_alias (__mig_dealloc_reply_port, mig_dealloc_reply_port)
> --
> 2.40.1
>
--
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.
- [PATCH v3 0/6] The remaining x86_64-gnu patches, Sergey Bugaev, 2023/04/29
- [PATCH v3 1/6] hurd: Implement sigreturn for x86_64, Sergey Bugaev, 2023/04/29
- [RFC PATCH v3 3/6] hurd: Replace reply port with a dead name on failed interruption, Sergey Bugaev, 2023/04/29
- Re: [RFC PATCH v3 3/6] hurd: Replace reply port with a dead name on failed interruption,
Samuel Thibault <=
- [PATCH v3 2/6] hurd: Implement longjmp for x86_64, Sergey Bugaev, 2023/04/29
- [RFC PATCH v3 5/6] hurd: Make it possible to call memcpy very early, Sergey Bugaev, 2023/04/29
- [DO NOT PUSH PATCH v3 6/6] TMP hurd: Lower BRK_START, Sergey Bugaev, 2023/04/29
- [PATCH v3 4/6] hurd: Add expected abilist files for x86_64, Sergey Bugaev, 2023/04/29