From 14c1461247a30ecc4b3ee29794e6a5f20bf02596 Mon Sep 17 00:00:00 2001 From: David Michael Date: Wed, 4 Jan 2017 18:27:48 -0800 Subject: [PATCH] sys-libs/glibc: avoid use-after-free in pthread This takes a patch from upstream Bugzilla by Alexey Makhalov. --- .../glibc-2.23-pthread-use-after-free.patch | 132 ++++++++++++++++++ ...bc-2.22-r4.ebuild => glibc-2.22-r5.ebuild} | 1 + 2 files changed, 133 insertions(+) create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/files/2.23/glibc-2.23-pthread-use-after-free.patch rename sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/{glibc-2.22-r4.ebuild => glibc-2.22-r5.ebuild} (99%) diff --git a/sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/files/2.23/glibc-2.23-pthread-use-after-free.patch b/sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/files/2.23/glibc-2.23-pthread-use-after-free.patch new file mode 100644 index 0000000000..c9734c0a15 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/files/2.23/glibc-2.23-pthread-use-after-free.patch @@ -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 +@@ -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); diff --git a/sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/glibc-2.22-r4.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/glibc-2.22-r5.ebuild similarity index 99% rename from sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/glibc-2.22-r4.ebuild rename to sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/glibc-2.22-r5.ebuild index a3dfd72615..eceae7cc35 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/glibc-2.22-r4.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-libs/glibc/glibc-2.22-r5.ebuild @@ -167,6 +167,7 @@ eblit-src_prepare-post() { ## 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-c-utf8-locale.patch + epatch "${FILESDIR}"/2.23/glibc-2.23-pthread-use-after-free.patch if use hardened ; then # We don't enable these for non-hardened as the output is very terse --