From patchwork Sat Apr 29 20:18:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 68554 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EB6F13857716 for ; Sat, 29 Apr 2023 20:19:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EB6F13857716 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1682799542; bh=tl+Qb3hhp3REer9N3xEUKijLqLT0EO8S4fPJFv0cnCc=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=T4fEmtH7L0C00QDJ9ff/jrDGP6ZC68+k1RnF+lRdQNQ+jSfotWu2ddtdjAOxHm8XR pbtsI9FOq3U7JT0XbVn0wEAIUR28AyoR0RyqyaZIGvHA+LIuT8A8tWqRIhCSdZZTIa +hQuYSbCEniQSFwV3S9EVq+3WUzZIrsHGhAnPmh0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by sourceware.org (Postfix) with ESMTPS id 5587A385842C for ; Sat, 29 Apr 2023 20:18:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5587A385842C Received: by mail-lf1-x12d.google.com with SMTP id 2adb3069b0e04-4efe8991b8aso1527529e87.0 for ; Sat, 29 Apr 2023 13:18:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682799508; x=1685391508; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tl+Qb3hhp3REer9N3xEUKijLqLT0EO8S4fPJFv0cnCc=; b=EHSBU+AGICDVK+vvtuoOytdUemigLh6eJ5drJvOT+HjXGBlSa7X6IExHJ93YiaVk1D QknstT0mYFIhe4tFecrrt+1PfLlQUKANnPzl8w2kt6xvcT8RQ+wCOaZLhnkamh6JZfg8 AFgO3MDWzKfnJORcw4+lmCDsCaWtokcByUe2gi9lY8VSvpWMIJF9K5ajRN+UCwBKG3id uBL2G8izzy2n2WE1OCJTWSbZkSiErEvCaSMfMspyifXkWb09gY3cYubvjKHjRkc2deqO euDeMaJ6DYbqF4pA31IROpp/XorUJYQTQ+ROtF/ZjanbjS0iwAsifrclV4sp5Dkd8X0u wyLA== X-Gm-Message-State: AC+VfDyS8f61luHdCfPgO9qbNpSEAcwttI1/dlqrGMGg6xpdzaTagnwn 97pGsswYC6Tn04KpL6/hhUbdc+Mnj4VVAg== X-Google-Smtp-Source: ACHHUZ7KZqDmhwWNp2c2iHyTEDLhZymKO1g1gT/biAMI/GRvjRQi8wpm0XJhWxV6qnum/nFw8edcfw== X-Received: by 2002:ac2:488e:0:b0:4e0:a426:6ddc with SMTP id x14-20020ac2488e000000b004e0a4266ddcmr2523095lfc.0.1682799507654; Sat, 29 Apr 2023 13:18:27 -0700 (PDT) Received: from surface-pro-6.. ([2a00:1370:818c:4a57:a7ac:6f45:1787:abcc]) by smtp.gmail.com with ESMTPSA id h25-20020ac250d9000000b004eb09820adbsm3905451lfm.105.2023.04.29.13.18.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 29 Apr 2023 13:18:27 -0700 (PDT) To: libc-alpha@sourceware.org Cc: bug-hurd@gnu.org, Samuel Thibault Subject: [RFC PATCH v3 3/6] hurd: Replace reply port with a dead name on failed interruption Date: Sat, 29 Apr 2023 23:18:19 +0300 Message-Id: <20230429201822.2605207-4-bugaevc@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230429201822.2605207-1-bugaevc@gmail.com> References: <20230429201822.2605207-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" 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 --- 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)