This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
PATCH: PR libc/11214: There is a race condition in ld.so withCLONE_VM
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Thu, 28 Jan 2010 17:31:45 -0800
- Subject: PATCH: PR libc/11214: There is a race condition in ld.so withCLONE_VM
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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