This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: PR libc/11214: There is a race condition in ld.so withCLONE_VM


When clone is called with CLONE_VM from a signle thread application, TLS
may be shared by parent and child processes. Since x86-64 ld.so always
uses TLS,  we have a race condition when both parent and child processes
accesses ld.so's TLS data. This patch duplicates the TLS area for single
thread process if CLONE_VM is used without CLONE_SETTLS.


H.J.
---
2010-01-28  H.J. Lu  <hongjiu.lu@intel.com>

	PR libc/11214
	* sysdeps/unix/sysv/linux/x86_64/clone.S: Don't define
	weak alias for clone if RESET_PID is defined.

nptl/

2010-01-28  H.J. Lu  <hongjiu.lu@intel.com>

	PR libc/11214
	* sysdeps/unix/sysv/linux/x86_64/clone-tls.c: New.
	* sysdeps/unix/sysv/linux/x86_64/pt-clone.S: Likewise.

	* sysdeps/unix/sysv/linux/x86_64/Makefile
	(libpthread-sysdep_routines): Add pt-clone.
	(sysdep_routines): Add clone-tls for misc.

	* sysdeps/unix/sysv/linux/x86_64/Versions: Add clone to
	libpthread.

diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile b/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
index b32ce29..4387a33 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -1,4 +1,10 @@
 ifeq ($(subdir),nptl)
 CFLAGS-pt-initfini.s = -g0 -fPIC -fno-inline-functions \
 		       -fno-asynchronous-unwind-tables $(fno-unit-at-a-time)
+
+libpthread-sysdep_routines += pt-clone
+endif
+
+ifeq ($(subdir),misc)
+sysdep_routines += clone-tls
 endif
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/Versions b/nptl/sysdeps/unix/sysv/linux/x86_64/Versions
index 3b111dd..a0116b0 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/Versions
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/Versions
@@ -5,3 +5,8 @@ librt {
     timer_settime;
   }
 }
+libpthread {
+  GLIBC_2.2.5 {
+    clone;
+  }
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/clone-tls.c b/nptl/sysdeps/unix/sysv/linux/x86_64/clone-tls.c
new file mode 100644
index 0000000..67ad767
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/clone-tls.c
@@ -0,0 +1,51 @@
+/* Copyright (C) 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <tls.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <pthreadP.h>
+
+int
+__clone_tls (int (*fn) (void *arg), void *child_stack, int flags,
+	     void *arg_p, ...)
+{
+  long ctid, ptid;
+  struct pthread *pd;
+  va_list arg;
+
+  va_start (arg, arg_p);
+  ctid = va_arg (arg, long);
+  pd = va_arg (arg, struct pthread *);
+  ptid = va_arg (arg, long);
+  va_end (arg);
+
+  if ((flags & (CLONE_VM | CLONE_SETTLS)) == CLONE_VM)
+    {
+      /* We have to clone TLS since TLS is always used in ld.so even
+	 for single thread application.  */
+      pd = malloc (sizeof (struct pthread));
+      memcpy (pd, THREAD_SELF, sizeof (struct pthread));
+      flags |= CLONE_SETTLS;
+    }
+
+  return __clone (fn, child_stack, flags, arg_p, ptid, pd, ctid);
+}
+
+weak_alias (__clone_tls, clone);
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pt-clone.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pt-clone.S
new file mode 100644
index 0000000..1bb3cc6
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pt-clone.S
@@ -0,0 +1,28 @@
+/* Copyright (C) 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+	.text
+ENTRY (clone)
+#ifdef SHARED
+	jmp	__clone@PLT
+#else
+	jmp	__clone
+#endif
+END(clone)
diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S
index db42f20..05e592d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/clone.S
+++ b/sysdeps/unix/sysv/linux/x86_64/clone.S
@@ -121,4 +121,6 @@ L(thread_start):
 	cfi_startproc;
 PSEUDO_END (BP_SYM (__clone))
 
+#ifndef RESET_PID
 weak_alias (BP_SYM (__clone), BP_SYM (clone))
+#endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]