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>
... | ... |
@@ -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); |