Merge pull request #2351 from dm0-/fix-glibc

sys-libs/glibc: avoid use-after-free in pthread
This commit is contained in:
David Michael 2017-01-04 18:41:21 -08:00 committed by GitHub
commit 6b941834eb
2 changed files with 133 additions and 0 deletions

View File

@ -0,0 +1,132 @@
diff -Naur glibc-2.22_orig/nptl/createthread.c glibc-2.22/nptl/createthread.c
--- glibc-2.22_orig/nptl/createthread.c 2015-08-04 23:42:21.000000000 -0700
+++ glibc-2.22/nptl/createthread.c 2016-09-28 11:27:50.831206703 -0700
@@ -25,13 +25,13 @@
static int
create_thread (struct pthread *pd, const struct pthread_attr *attr,
- bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
+ bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
{
/* If the implementation needs to do some tweaks to the thread after
it has been created at the OS level, it can set STOPPED_START here. */
- pd->stopped_start = stopped_start;
- if (__glibc_unlikely (stopped_start))
+ pd->stopped_start = *stopped_start;
+ if (__glibc_unlikely (*stopped_start))
/* We make sure the thread does not run far by forcing it to get a
lock. We lock it here too so that the new thread cannot continue
until we tell it to. */
diff -Naur glibc-2.22_orig/nptl/pthread_create.c glibc-2.22/nptl/pthread_create.c
--- glibc-2.22_orig/nptl/pthread_create.c 2015-08-04 23:42:21.000000000 -0700
+++ glibc-2.22/nptl/pthread_create.c 2016-09-28 11:31:20.839209223 -0700
@@ -72,7 +72,7 @@
case it is responsible for doing its own cleanup. */
static int create_thread (struct pthread *pd, const struct pthread_attr *attr,
- bool stopped_start, STACK_VARIABLES_PARMS,
+ bool *stopped_start, STACK_VARIABLES_PARMS,
bool *thread_ran);
#include <createthread.c>
@@ -633,14 +633,16 @@
that cares whether the thread count is correct. */
atomic_increment (&__nptl_nthreads);
+ bool stopped_start = false;
bool thread_ran = false;
/* Start the thread. */
if (__glibc_unlikely (report_thread_creation (pd)))
{
+ stopped_start = true;
/* Create the thread. We always create the thread stopped
so that it does not get far before we tell the debugger. */
- retval = create_thread (pd, iattr, true, STACK_VARIABLES_ARGS,
+ retval = create_thread (pd, iattr, &stopped_start, STACK_VARIABLES_ARGS,
&thread_ran);
if (retval == 0)
{
@@ -667,7 +669,7 @@
}
}
else
- retval = create_thread (pd, iattr, false, STACK_VARIABLES_ARGS,
+ retval = create_thread (pd, iattr, &stopped_start, STACK_VARIABLES_ARGS,
&thread_ran);
if (__glibc_unlikely (retval != 0))
@@ -701,7 +703,8 @@
}
else
{
- if (pd->stopped_start)
+ /* do not use pd->stopped_start to avoid use after free */
+ if (stopped_start)
/* The thread blocked on this lock either because we're doing TD_CREATE
event reporting, or for some other reason that create_thread chose.
Now let it run free. */
diff -Naur glibc-2.22_orig/sysdeps/nacl/createthread.c glibc-2.22/sysdeps/nacl/createthread.c
--- glibc-2.22_orig/sysdeps/nacl/createthread.c 2015-08-04 23:42:21.000000000 -0700
+++ glibc-2.22/sysdeps/nacl/createthread.c 2016-09-28 11:27:34.983206513 -0700
@@ -32,12 +32,12 @@
static int
create_thread (struct pthread *pd, const struct pthread_attr *attr,
- bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
+ bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
{
pd->tid = __nacl_get_tid (pd);
- pd->stopped_start = stopped_start;
- if (__glibc_unlikely (stopped_start))
+ pd->stopped_start = *stopped_start;
+ if (__glibc_unlikely (*stopped_start))
/* We make sure the thread does not run far by forcing it to get a
lock. We lock it here too so that the new thread cannot continue
until we tell it to. */
diff -Naur glibc-2.22_orig/sysdeps/unix/sysv/linux/createthread.c glibc-2.22/sysdeps/unix/sysv/linux/createthread.c
--- glibc-2.22_orig/sysdeps/unix/sysv/linux/createthread.c 2015-08-04 23:42:21.000000000 -0700
+++ glibc-2.22/sysdeps/unix/sysv/linux/createthread.c 2016-09-28 11:27:18.275206312 -0700
@@ -46,7 +46,7 @@
static int
create_thread (struct pthread *pd, const struct pthread_attr *attr,
- bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
+ bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
{
/* Determine whether the newly created threads has to be started
stopped since we have to set the scheduling parameters or set the
@@ -54,10 +54,10 @@
if (attr != NULL
&& (__glibc_unlikely (attr->cpuset != NULL)
|| __glibc_unlikely ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)))
- stopped_start = true;
+ *stopped_start = true;
- pd->stopped_start = stopped_start;
- if (__glibc_unlikely (stopped_start))
+ pd->stopped_start = *stopped_start;
+ if (__glibc_unlikely (*stopped_start))
/* We make sure the thread does not run far by forcing it to get a
lock. We lock it here too so that the new thread cannot continue
until we tell it to. */
@@ -117,7 +117,7 @@
/* Set the affinity mask if necessary. */
if (attr->cpuset != NULL)
{
- assert (stopped_start);
+ assert (*stopped_start);
res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
attr->cpusetsize, attr->cpuset);
@@ -140,7 +140,7 @@
/* Set the scheduling parameters. */
if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
{
- assert (stopped_start);
+ assert (*stopped_start);
res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
pd->schedpolicy, &pd->schedparam);

View File

@ -167,6 +167,7 @@ eblit-src_prepare-post() {
## COREOS: features and bug fixes missing from the Gentoo patch set. ## COREOS: features and bug fixes missing from the Gentoo patch set.
epatch "${FILESDIR}"/2.23/glibc-2.23-gshadow-handle-erange.patch epatch "${FILESDIR}"/2.23/glibc-2.23-gshadow-handle-erange.patch
epatch "${FILESDIR}"/2.23/glibc-2.23-c-utf8-locale.patch epatch "${FILESDIR}"/2.23/glibc-2.23-c-utf8-locale.patch
epatch "${FILESDIR}"/2.23/glibc-2.23-pthread-use-after-free.patch
if use hardened ; then if use hardened ; then
# We don't enable these for non-hardened as the output is very terse -- # We don't enable these for non-hardened as the output is very terse --