about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2018-03-18 20:27:16 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2018-03-18 20:43:59 +0100
commit72e7ffc37fd59e093eb6352c9e0abde2112a9346 (patch)
tree6dbb383410ae24b2dc1151532c88b50f3b009e3d
parent20bc801b3d4ba1eb1c9704a529b6720f096a14e5 (diff)
downloadglibc-72e7ffc37fd59e093eb6352c9e0abde2112a9346.tar.gz
glibc-72e7ffc37fd59e093eb6352c9e0abde2112a9346.tar.xz
glibc-72e7ffc37fd59e093eb6352c9e0abde2112a9346.zip
Hurd: fix port leak in TLS
	* sysdeps/mach/hurd/i386/tls.h (_hurd_tls_init): Use a temporary
	thread reference.
-rw-r--r--ChangeLog5
-rw-r--r--sysdeps/mach/hurd/i386/tls.h21
2 files changed, 18 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 1a34efca45..ddf8c9c9d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-18  Richard Braun  <rbraun@sceen.net>
+
+	* sysdeps/mach/hurd/i386/tls.h (_hurd_tls_init): Use a temporary
+	thread reference.
+
 2018-03-18  Agustina Arzille  <avarzille@riseup.net>
 
 	* sysdeps/mach/libc-lock.h (__libc_cleanup_frame): Define structure.
diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h
index c443552df4..771c94ff95 100644
--- a/sysdeps/mach/hurd/i386/tls.h
+++ b/sysdeps/mach/hurd/i386/tls.h
@@ -111,36 +111,41 @@ static inline const char * __attribute__ ((unused))
 _hurd_tls_init (tcbhead_t *tcb)
 {
   HURD_TLS_DESC_DECL (desc, tcb);
+  thread_t self = __mach_thread_self ();
+  const char *msg = NULL;
 
   /* This field is used by TLS accesses to get our "thread pointer"
      from the TLS point of view.  */
   tcb->tcb = tcb;
 
-  /* Cache our thread port.  */
-  tcb->self = __mach_thread_self ();
-
   /* Get the first available selector.  */
   int sel = -1;
-  error_t err = __i386_set_gdt (tcb->self, &sel, desc);
+  error_t err = __i386_set_gdt (self, &sel, desc);
   if (err == MIG_BAD_ID)
     {
       /* Old kernel, use a per-thread LDT.  */
       sel = 0x27;
-      err = __i386_set_ldt (tcb->self, sel, &desc, 1);
+      err = __i386_set_ldt (self, sel, &desc, 1);
       assert_perror (err);
       if (err)
-	return "i386_set_ldt failed";
+      {
+	msg = "i386_set_ldt failed";
+	goto out;
+      }
     }
   else if (err)
     {
       assert_perror (err); /* Separate from above with different line #. */
-      return "i386_set_gdt failed";
+      msg = "i386_set_gdt failed";
+      goto out;
     }
 
   /* Now install the new selector.  */
   asm volatile ("mov %w0, %%gs" :: "q" (sel));
 
-  return 0;
+out:
+  __mach_port_deallocate (__mach_task_self (), self);
+  return msg;
 }
 
 /* Code to initially initialize the thread pointer.  This might need