Browse Source

fix TLS memory leak with dlopen

Signed-off-by: Mingxiang Lu <lu.mingxiang@h3c.com>
Signed-off-by: Waldemar Brodkorb <wbx@uclibc-ng.org>
Mingxiang Lu 1 tháng trước cách đây
mục cha
commit
f8028afeaf

+ 5 - 0
libpthread/nptl/allocatestack.c

@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <sys/param.h>
+#include <dl-tls.h>
 #include <tls.h>
 #include <lowlevellock.h>
 #include <link.h>
@@ -241,6 +242,10 @@ get_cached_stack (size_t *sizep, void **memp)
 
   /* Clear the DTV.  */
   dtv_t *dtv = GET_DTV (TLS_TPADJ (result));
+  for (size_t cnt = 0; cnt < dtv[-1].counter; ++cnt)
+    if (! dtv[1 + cnt].pointer.is_static
+	      && dtv[1 + cnt].pointer.val != TLS_DTV_UNALLOCATED)
+      free (dtv[1 + cnt].pointer.val);
   memset (dtv, '\0', (dtv[-1].counter + 1) * sizeof (dtv_t));
 
   /* Re-initialize the TLS.  */

+ 3 - 0
libpthread/nptl/sysdeps/arc/dl-tls.h

@@ -26,3 +26,6 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/arm/dl-tls.h

@@ -26,3 +26,6 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 2 - 0
libpthread/nptl/sysdeps/csky/dl-tls.h

@@ -14,3 +14,5 @@ typedef struct
 
 extern void *__tls_get_addr (tls_index *ti);
 
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 0 - 2
libpthread/nptl/sysdeps/generic/dl-tls.c

@@ -45,8 +45,6 @@
    to allow dynamic loading of modules defining IE-model TLS data.  */
 # define TLS_STATIC_SURPLUS	64 + DL_NNS * 100
 
-/* Value used for dtv entries for which the allocation is delayed.  */
-# define TLS_DTV_UNALLOCATED	((void *) -1l)
 
 #ifndef SHARED
 extern dtv_t static_dtv;

+ 3 - 0
libpthread/nptl/sysdeps/i386/dl-tls.h

@@ -59,3 +59,6 @@ strong_alias (___tls_get_addr, ___tls_get_addr_internal)
 
 # endif
 #endif
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/metag/dl-tls.h

@@ -26,3 +26,6 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/microblaze/dl-tls.h

@@ -24,3 +24,6 @@ typedef struct
 } tls_index;
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/mips/dl-tls.h

@@ -43,3 +43,6 @@ extern void *__tls_get_addr (tls_index *ti);
 
 # define GET_ADDR_OFFSET	(ti->ti_offset + TLS_DTV_OFFSET)
 # define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/or1k/dl-tls.h

@@ -24,3 +24,6 @@ typedef struct
 } tls_index;
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/powerpc/dl-tls.h

@@ -46,3 +46,6 @@ extern void *__tls_get_addr (tls_index *ti);
 # define GET_ADDR_OFFSET	(ti->ti_offset + TLS_DTV_OFFSET)
 # define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
 #endif
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/riscv32/dl-tls.h

@@ -32,3 +32,6 @@ extern void *__tls_get_addr (tls_index *ti);
 
 #define GET_ADDR_OFFSET        (ti->ti_offset + TLS_DTV_OFFSET)
 #define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/riscv64/dl-tls.h

@@ -32,3 +32,6 @@ extern void *__tls_get_addr (tls_index *ti);
 
 #define GET_ADDR_OFFSET        (ti->ti_offset + TLS_DTV_OFFSET)
 #define __TLS_GET_ADDR(__ti)	(__tls_get_addr (__ti) - TLS_DTV_OFFSET)
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/sh/dl-tls.h

@@ -26,3 +26,6 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/sparc/dl-tls.h

@@ -26,3 +26,6 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/x86_64/dl-tls.h

@@ -26,3 +26,6 @@ typedef struct
 
 
 extern void *__tls_get_addr (tls_index *ti);
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED	((void *) -1l)

+ 3 - 0
libpthread/nptl/sysdeps/xtensa/dl-tls.h

@@ -70,3 +70,6 @@ extern ptrdiff_t attribute_hidden
   _dl_tlsdesc_dynamic(struct tlsdesc_dynamic_arg *);
 #endif
 #endif
+
+/* Value used for dtv entries for which the allocation is delayed.  */
+#define TLS_DTV_UNALLOCATED    ((void *) -1l)