]> sourceware.org Git - glibc.git/commitdiff
x86: Fix THREAD_SELF definition to avoid ld.so crash (bug 27004)
authorJakub Jelinek <jakub@redhat.com>
Thu, 3 Dec 2020 12:33:44 +0000 (13:33 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Thu, 3 Dec 2020 12:48:55 +0000 (13:48 +0100)
The previous definition of THREAD_SELF did not tell the compiler
that %fs (or %gs) usage is invalid for the !DL_LOOKUP_GSCOPE_LOCK
case in _dl_lookup_symbol_x.  As a result, ld.so could try to use the
TCB before it was initialized.

As the comment in tls.h explains, asm volatile is undesirable here.
Using the __seg_fs (or __seg_gs) namespace does not interfere with
optimization, and expresses that THREAD_SELF is potentially trapping.

sysdeps/i386/nptl/tls.h
sysdeps/x86_64/nptl/tls.h

index b74347bacd08d6c74b4e9e2eb30eba139592a390..ab98c24a025c4e1c5f7133f49685d4aed8f305d0 100644 (file)
@@ -234,11 +234,16 @@ tls_fill_user_desc (union user_desc_init *desc,
    assignments like
        pthread_descr self = thread_self();
    do not get optimized away.  */
-# define THREAD_SELF \
+# if __GNUC_PREREQ (6, 0)
+#  define THREAD_SELF \
+  (*(struct pthread *__seg_gs *) offsetof (struct pthread, header.self))
+# else
+#  define THREAD_SELF \
   ({ struct pthread *__self;                                                 \
      asm ("movl %%gs:%c1,%0" : "=r" (__self)                                 \
          : "i" (offsetof (struct pthread, header.self)));                    \
      __self;})
+# endif
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
 # define DB_THREAD_SELF \
index a08bf972ded86872337ab0c063bcb78bba459c2e..ccb5f24d920b38c398ad4cecbbaac0cb6d406a17 100644 (file)
@@ -180,11 +180,16 @@ _Static_assert (offsetof (tcbhead_t, __glibc_unused2) == 0x80,
    assignments like
        pthread_descr self = thread_self();
    do not get optimized away.  */
-# define THREAD_SELF \
+# if __GNUC_PREREQ (6, 0)
+#  define THREAD_SELF \
+  (*(struct pthread *__seg_fs *) offsetof (struct pthread, header.self))
+# else
+#  define THREAD_SELF \
   ({ struct pthread *__self;                                                 \
      asm ("mov %%fs:%c1,%0" : "=r" (__self)                                  \
          : "i" (offsetof (struct pthread, header.self)));                    \
      __self;})
+# endif
 
 /* Magic for libthread_db to know how to do THREAD_SELF.  */
 # define DB_THREAD_SELF_INCLUDE  <sys/reg.h> /* For the FS constant.  */
This page took 0.047581 seconds and 5 git commands to generate.