[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH glibc 25/34] hurd: Improve reply port handling when exiting s
From: |
Sergey Bugaev |
Subject: |
[RFC PATCH glibc 25/34] hurd: Improve reply port handling when exiting signal handlers |
Date: |
Sun, 19 Mar 2023 18:10:08 +0300 |
If we're doing signals, that means we've already got the signal thread
running, and that implies TLS having been set up. So we know that
__hurd_local_reply_port will resolve to THREAD_SELF->reply_port, and can
access that directly using the THREAD_GETMEM and THREAD_SETMEM macros.
This avoids potential miscompilations, and should also be a tiny bit
faster.
Also, use mach_port_mod_refs () and not mach_port_destroy () to destroy
the receive right. mach_port_destroy () should *never* be used on
mach_task_self (); this can easily lead to port use-after-free
vulnerabilities if the task has any other references to the same port.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
---
NOTE: I don't really understand why sigunwind wants to destroy both its
current reply port and user's reply port. Prior to commit
fb304035c41c7ee2afede51e5e8568974549ba5e, it was *restoring* the user's
reply port, in which case it actually made sense to destroy the current
reply port. Post-fb304035c41c7ee2afede51e5e8568974549ba5e, wouldn't it
be better to just keep using the current reply port, destroying the
user's one?
hurd/sigunwind.c | 24 +++++++++++-------------
sysdeps/mach/hurd/i386/sigreturn.c | 21 +++++----------------
2 files changed, 16 insertions(+), 29 deletions(-)
diff --git a/hurd/sigunwind.c b/hurd/sigunwind.c
index edd40b14..399e6900 100644
--- a/hurd/sigunwind.c
+++ b/hurd/sigunwind.c
@@ -18,7 +18,6 @@
#include <hurd.h>
#include <thread_state.h>
-#include <hurd/threadvar.h>
#include <jmpbuf-unwind.h>
#include <assert.h>
#include <stdint.h>
@@ -39,19 +38,18 @@ _hurdsig_longjmp_from_handler (void *data, jmp_buf env, int
val)
{
/* Destroy the MiG reply port used by the signal handler, and restore
the reply port in use by the thread when interrupted. */
- mach_port_t *reply_port = &__hurd_local_reply_port;
- if (*reply_port)
- {
- mach_port_t port = *reply_port;
- /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port
- not to get another reply port, but avoids mig_dealloc_reply_port
- trying to deallocate it after the receive fails (which it will,
- because the reply port will be bogus, regardless). */
- *reply_port = MACH_PORT_DEAD;
- __mach_port_destroy (__mach_task_self (), port);
- }
+ mach_port_t reply_port = THREAD_GETMEM (THREAD_SELF, reply_port);
+ /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to
+ get another reply port, but avoids mig_dealloc_reply_port trying to
+ deallocate it after the receive fails (which it will, because the
+ reply port will be bogus, regardless). */
+ THREAD_SETMEM (THREAD_SELF, reply_port, MACH_PORT_DEAD);
+ if (MACH_PORT_VALID (reply_port))
+ __mach_port_mod_refs (__mach_task_self (), reply_port,
+ MACH_PORT_RIGHT_RECEIVE, -1);
if (scp->sc_reply_port)
- __mach_port_destroy (__mach_task_self (), scp->sc_reply_port);
+ __mach_port_mod_refs (__mach_task_self (), scp->sc_reply_port,
+ MACH_PORT_RIGHT_RECEIVE, -1);
}
__spin_lock (&ss->lock);
diff --git a/sysdeps/mach/hurd/i386/sigreturn.c
b/sysdeps/mach/hurd/i386/sigreturn.c
index db1a01f3..29c9629f 100644
--- a/sysdeps/mach/hurd/i386/sigreturn.c
+++ b/sysdeps/mach/hurd/i386/sigreturn.c
@@ -19,7 +19,6 @@ register int *sp asm ("%esp");
#include <hurd.h>
#include <hurd/signal.h>
-#include <hurd/threadvar.h>
#include <hurd/msg.h>
#include <stdlib.h>
#include <string.h>
@@ -59,7 +58,7 @@ __sigreturn (struct sigcontext *scp)
{
struct hurd_sigstate *ss;
struct hurd_userlink *link = (void *) &scp[1];
- mach_port_t *reply_port;
+ mach_port_t reply_port;
if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK))
{
@@ -101,20 +100,10 @@ __sigreturn (struct sigcontext *scp)
/* Destroy the MiG reply port used by the signal handler, and restore the
reply port in use by the thread when interrupted. */
- reply_port = &__hurd_local_reply_port;
- if (*reply_port)
- {
- mach_port_t port = *reply_port;
-
- /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to
- get another reply port, but avoids mig_dealloc_reply_port trying to
- deallocate it after the receive fails (which it will, because the
- reply port will be bogus, whether we do this or not). */
- *reply_port = MACH_PORT_DEAD;
-
- __mach_port_destroy (__mach_task_self (), port);
- }
- *reply_port = scp->sc_reply_port;
+ reply_port = THREAD_GETMEM (THREAD_SELF, reply_port);
+ THREAD_SETMEM (THREAD_SELF, reply_port, scp->sc_reply_port);
+ __mach_port_mod_refs (__mach_task_self (), reply_port,
+ MACH_PORT_RIGHT_RECEIVE, -1);
if (scp->sc_fpused)
/* Restore the FPU state. Mach conveniently stores the state
--
2.39.2
- [RFC PATCH glibc 10/34] stdio-common: Fix building when !IS_IN (libc), (continued)
- [RFC PATCH glibc 10/34] stdio-common: Fix building when !IS_IN (libc), Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 11/34] mach, hurd: Drop __libc_lock_self0, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 08/34] hurd: Disable O_TRUNC and FS_RETRY_MAGICAL in rtld, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 17/34] hurd: Implement x86_64/intr-msg.h, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 16/34] hurd: Add sys/ucontext.h and sigcontext.h for x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 18/34] hurd: Port trampoline.c to x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 19/34] hurd: Move a couple of singal-related files to x86, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 24/34] hurd: Only check for TLS initialization inside rtld or in static builds, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 21/34] x86_64: Add rtld-stpncpy & rtld-strncpy, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 23/34] elf: Stop including tls.h in ldsodefs.h, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 25/34] hurd: Improve reply port handling when exiting signal handlers,
Sergey Bugaev <=
- [RFC PATCH glibc 22/34] htl: Implement thread_set_pcsptp for x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 29/34] hurd: Add vm_param.h for x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 31/34] hurd: Microoptimize _hurd_self_sigstate (), Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 26/34] hurd: Remove __hurd_local_reply_port, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 20/34] htl: Add tcb-offsets.sym for x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 27/34] hurd: Don't leak __hurd_reply_port0, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 28/34] hurd: Implement _hurd_longjmp_thread_state for x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 30/34] hurd: Implement longjmp for x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 32/34] hurd: Implement sigreturn for x86_64, Sergey Bugaev, 2023/03/19
- [RFC PATCH glibc 33/34] hurd: Create abilist files for lib{mach, hurd}user, Sergey Bugaev, 2023/03/19