Browse code

glibc: fix use after free in pthread_create

Change-Id: I003d3b032c5504790bacb38e12c291f38e224760
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/1512
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Tested-by: suezzelur <anishs@vmware.com>

Alexey Makhalov authored on 2016/09/29 04:32:10
Showing 2 changed files
... ...
@@ -6,7 +6,7 @@
6 6
 Summary:	Main C library
7 7
 Name:		glibc
8 8
 Version:	2.22
9
-Release:	8%{?dist}
9
+Release:	9%{?dist}
10 10
 License:	LGPLv2+
11 11
 URL:		http://www.gnu.org/software/libc
12 12
 Group:		Applications/System
... ...
@@ -25,6 +25,7 @@ Patch5:		glibc-fix-CVE-2014-9761-1.patch
25 25
 Patch6:		glibc-fix-CVE-2014-9761-2.patch
26 26
 Patch7:		glibc-fix-CVE-2014-9761-3.patch
27 27
 Patch8:		glibc-fix-CVE-2014-9761-4.patch
28
+Patch9:		pthread_create-fix-use-after-free.patch
28 29
 Provides:	rtld(GNU_HASH)
29 30
 Requires:       filesystem
30 31
 %description
... ...
@@ -59,6 +60,7 @@ sed -i 's/\\$$(pwd)/`pwd`/' timezone/Makefile
59 59
 %patch6 -p1
60 60
 %patch7 -p1
61 61
 %patch8 -p1
62
+%patch9 -p1
62 63
 install -vdm 755 %{_builddir}/%{name}-build
63 64
 # do not try to explicitly provide GLIBC_PRIVATE versioned libraries
64 65
 %define __find_provides %{_builddir}/%{name}-%{version}/find_provides.sh
... ...
@@ -189,6 +191,8 @@ printf "Creating ldconfig cache\n";/sbin/ldconfig
189 189
 
190 190
 
191 191
 %changelog
192
+*	Wed Sep 28 2016 Alexey Makhalov <amakhalov@vmware.com> 2.22-9
193
+-	Added pthread_create-fix-use-after-free.patch
192 194
 *	Tue May 24 2016 Priyesh Padmavilasom <ppadmavilasom@vmware.com> 2.22-8
193 195
 -	GA - Bump release of all rpms
194 196
 *	Mon May 23 2016 Divya Thaluru <dthaluru@vmware.com> 2.22-7
195 197
new file mode 100644
... ...
@@ -0,0 +1,132 @@
0
+diff -Naur glibc-2.22_orig/nptl/createthread.c glibc-2.22/nptl/createthread.c
1
+--- glibc-2.22_orig/nptl/createthread.c	2015-08-04 23:42:21.000000000 -0700
2
+@@ -25,13 +25,13 @@
3
+ 
4
+ static int
5
+ create_thread (struct pthread *pd, const struct pthread_attr *attr,
6
+-	       bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
7
++	       bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
8
+ {
9
+   /* If the implementation needs to do some tweaks to the thread after
10
+      it has been created at the OS level, it can set STOPPED_START here.  */
11
+ 
12
+-  pd->stopped_start = stopped_start;
13
+-  if (__glibc_unlikely (stopped_start))
14
++  pd->stopped_start = *stopped_start;
15
++  if (__glibc_unlikely (*stopped_start))
16
+     /* We make sure the thread does not run far by forcing it to get a
17
+        lock.  We lock it here too so that the new thread cannot continue
18
+        until we tell it to.  */
19
+diff -Naur glibc-2.22_orig/nptl/pthread_create.c glibc-2.22/nptl/pthread_create.c
20
+--- glibc-2.22_orig/nptl/pthread_create.c	2015-08-04 23:42:21.000000000 -0700
21
+@@ -72,7 +72,7 @@
22
+    case it is responsible for doing its own cleanup.  */
23
+ 
24
+ static int create_thread (struct pthread *pd, const struct pthread_attr *attr,
25
+-			  bool stopped_start, STACK_VARIABLES_PARMS,
26
++			  bool *stopped_start, STACK_VARIABLES_PARMS,
27
+ 			  bool *thread_ran);
28
+ 
29
+ #include <createthread.c>
30
+@@ -633,14 +633,16 @@
31
+      that cares whether the thread count is correct.  */
32
+   atomic_increment (&__nptl_nthreads);
33
+ 
34
++  bool stopped_start = false;
35
+   bool thread_ran = false;
36
+ 
37
+   /* Start the thread.  */
38
+   if (__glibc_unlikely (report_thread_creation (pd)))
39
+     {
40
++      stopped_start = true;
41
+       /* Create the thread.  We always create the thread stopped
42
+ 	 so that it does not get far before we tell the debugger.  */
43
+-      retval = create_thread (pd, iattr, true, STACK_VARIABLES_ARGS,
44
++      retval = create_thread (pd, iattr, &stopped_start, STACK_VARIABLES_ARGS,
45
+ 			      &thread_ran);
46
+       if (retval == 0)
47
+ 	{
48
+@@ -667,7 +669,7 @@
49
+ 	}
50
+     }
51
+   else
52
+-    retval = create_thread (pd, iattr, false, STACK_VARIABLES_ARGS,
53
++    retval = create_thread (pd, iattr, &stopped_start, STACK_VARIABLES_ARGS,
54
+ 			    &thread_ran);
55
+ 
56
+   if (__glibc_unlikely (retval != 0))
57
+@@ -701,7 +703,8 @@
58
+     }
59
+   else
60
+     {
61
+-      if (pd->stopped_start)
62
++      /* do not use pd->stopped_start to avoid use after free */
63
++      if (stopped_start)
64
+ 	/* The thread blocked on this lock either because we're doing TD_CREATE
65
+ 	   event reporting, or for some other reason that create_thread chose.
66
+ 	   Now let it run free.  */
67
+diff -Naur glibc-2.22_orig/sysdeps/nacl/createthread.c glibc-2.22/sysdeps/nacl/createthread.c
68
+--- glibc-2.22_orig/sysdeps/nacl/createthread.c	2015-08-04 23:42:21.000000000 -0700
69
+@@ -32,12 +32,12 @@
70
+ 
71
+ static int
72
+ create_thread (struct pthread *pd, const struct pthread_attr *attr,
73
+-	       bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
74
++	       bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
75
+ {
76
+   pd->tid = __nacl_get_tid (pd);
77
+ 
78
+-  pd->stopped_start = stopped_start;
79
+-  if (__glibc_unlikely (stopped_start))
80
++  pd->stopped_start = *stopped_start;
81
++  if (__glibc_unlikely (*stopped_start))
82
+     /* We make sure the thread does not run far by forcing it to get a
83
+        lock.  We lock it here too so that the new thread cannot continue
84
+        until we tell it to.  */
85
+diff -Naur glibc-2.22_orig/sysdeps/unix/sysv/linux/createthread.c glibc-2.22/sysdeps/unix/sysv/linux/createthread.c
86
+--- glibc-2.22_orig/sysdeps/unix/sysv/linux/createthread.c	2015-08-04 23:42:21.000000000 -0700
87
+@@ -46,7 +46,7 @@
88
+ 
89
+ static int
90
+ create_thread (struct pthread *pd, const struct pthread_attr *attr,
91
+-	       bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
92
++	       bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
93
+ {
94
+   /* Determine whether the newly created threads has to be started
95
+      stopped since we have to set the scheduling parameters or set the
96
+@@ -54,10 +54,10 @@
97
+   if (attr != NULL
98
+       && (__glibc_unlikely (attr->cpuset != NULL)
99
+ 	  || __glibc_unlikely ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)))
100
+-    stopped_start = true;
101
++    *stopped_start = true;
102
+ 
103
+-  pd->stopped_start = stopped_start;
104
+-  if (__glibc_unlikely (stopped_start))
105
++  pd->stopped_start = *stopped_start;
106
++  if (__glibc_unlikely (*stopped_start))
107
+     /* We make sure the thread does not run far by forcing it to get a
108
+        lock.  We lock it here too so that the new thread cannot continue
109
+        until we tell it to.  */
110
+@@ -117,7 +117,7 @@
111
+       /* Set the affinity mask if necessary.  */
112
+       if (attr->cpuset != NULL)
113
+ 	{
114
+-	  assert (stopped_start);
115
++	  assert (*stopped_start);
116
+ 
117
+ 	  res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
118
+ 				  attr->cpusetsize, attr->cpuset);
119
+@@ -140,7 +140,7 @@
120
+       /* Set the scheduling parameters.  */
121
+       if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
122
+ 	{
123
+-	  assert (stopped_start);
124
++	  assert (*stopped_start);
125
+ 
126
+ 	  res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
127
+ 				  pd->schedpolicy, &pd->schedparam);