1 |
tamiko 17/06/20 08:31:52 |
2 |
|
3 |
Added: |
4 |
00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch |
5 |
00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch |
6 |
00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch |
7 |
00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch |
8 |
00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch |
9 |
Log: |
10 |
glibc-2.25: update to patchset 5 |
11 |
|
12 |
Revision Changes Path |
13 |
1.1 src/patchsets/glibc/2.25/00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch |
14 |
|
15 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&view=markup |
16 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&content-type=text/plain |
17 |
|
18 |
Index: 00_all_0015-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch |
19 |
=================================================================== |
20 |
From 4d009d39ac9ede0369e268554a181b428f177a80 Mon Sep 17 00:00:00 2001 |
21 |
Message-Id: <4d009d39ac9ede0369e268554a181b428f177a80.1495998948.git.fweimer@××××××.com> |
22 |
In-Reply-To: <cover.1495998948.git.fweimer@××××××.com> |
23 |
References: <cover.1495998948.git.fweimer@××××××.com> |
24 |
From: Florian Weimer <fweimer@××××××.com> |
25 |
Date: Sun, 28 May 2017 20:37:40 +0200 |
26 |
Subject: [PATCH 1/3] rtld: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1 |
27 |
programs |
28 |
To: libc-alpha@××××××××××.org |
29 |
|
30 |
LD_LIBRARY_PATH can only be used to reorder system search paths, which |
31 |
is not useful functionality. |
32 |
--- |
33 |
elf/rtld.c | 3 ++- |
34 |
1 file changed, 2 insertions(+), 1 deletion(-) |
35 |
|
36 |
diff --git a/elf/rtld.c b/elf/rtld.c |
37 |
index 319ef06..824b6cf 100644 |
38 |
--- a/elf/rtld.c |
39 |
+++ b/elf/rtld.c |
40 |
@@ -2419,7 +2419,8 @@ process_envvars (enum mode *modep) |
41 |
|
42 |
case 12: |
43 |
/* The library search path. */ |
44 |
- if (memcmp (envline, "LIBRARY_PATH", 12) == 0) |
45 |
+ if (!__libc_enable_secure |
46 |
+ && memcmp (envline, "LIBRARY_PATH", 12) == 0) |
47 |
{ |
48 |
library_path = &envline[13]; |
49 |
break; |
50 |
-- |
51 |
2.9.4 |
52 |
|
53 |
|
54 |
|
55 |
|
56 |
1.1 src/patchsets/glibc/2.25/00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch |
57 |
|
58 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&view=markup |
59 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&content-type=text/plain |
60 |
|
61 |
Index: 00_all_0016-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch |
62 |
=================================================================== |
63 |
From ba67ba3275d47e0080f0e5f09d9f5102c000c97e Mon Sep 17 00:00:00 2001 |
64 |
Message-Id: <ba67ba3275d47e0080f0e5f09d9f5102c000c97e.1495998948.git.fweimer@××××××.com> |
65 |
In-Reply-To: <cover.1495998948.git.fweimer@××××××.com> |
66 |
References: <cover.1495998948.git.fweimer@××××××.com> |
67 |
From: Florian Weimer <fweimer@××××××.com> |
68 |
Date: Sun, 28 May 2017 20:44:52 +0200 |
69 |
Subject: [PATCH 3/3] rtld: Reject overly long LD_AUDIT path elements |
70 |
To: libc-alpha@××××××××××.org |
71 |
|
72 |
Also only process the last LD_AUDIT entry. |
73 |
--- |
74 |
elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
75 |
1 file changed, 95 insertions(+), 15 deletions(-) |
76 |
|
77 |
diff --git a/elf/rtld.c b/elf/rtld.c |
78 |
index cdddcf3..c9ddba1 100644 |
79 |
--- a/elf/rtld.c |
80 |
+++ b/elf/rtld.c |
81 |
@@ -100,13 +100,91 @@ strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) |
82 |
#endif |
83 |
|
84 |
|
85 |
-/* List of auditing DSOs. */ |
86 |
+/* LD_AUDIT variable contents. Must be processed before the |
87 |
+ audit_list below. */ |
88 |
+const char *audit_list_string; |
89 |
+ |
90 |
+/* Cyclic list of auditing DSOs. audit_list->next is the first |
91 |
+ element. */ |
92 |
static struct audit_list |
93 |
{ |
94 |
const char *name; |
95 |
struct audit_list *next; |
96 |
} *audit_list; |
97 |
|
98 |
+/* Iterator for audit_list_string followed by audit_list. */ |
99 |
+struct audit_list_iter |
100 |
+{ |
101 |
+ /* Tail of audit_list_string still needing processing, or NULL. */ |
102 |
+ const char *audit_list_tail; |
103 |
+ |
104 |
+ /* The list element returned in the previous iteration. NULL before |
105 |
+ the first element. */ |
106 |
+ struct audit_list *previous; |
107 |
+ |
108 |
+ /* Scratch buffer for returning a name which is part of |
109 |
+ audit_list_string. */ |
110 |
+ char fname[PATH_MAX]; |
111 |
+}; |
112 |
+ |
113 |
+/* Initialize an audit list iterator. */ |
114 |
+static void |
115 |
+audit_list_iter_init (struct audit_list_iter *iter) |
116 |
+{ |
117 |
+ iter->audit_list_tail = audit_list_string; |
118 |
+ iter->previous = NULL; |
119 |
+} |
120 |
+ |
121 |
+/* Iterate through both audit_list_string and audit_list. */ |
122 |
+static const char * |
123 |
+audit_list_iter_next (struct audit_list_iter *iter) |
124 |
+{ |
125 |
+ if (iter->audit_list_tail != NULL) |
126 |
+ { |
127 |
+ /* First iterate over audit_list_string. */ |
128 |
+ while (*iter->audit_list_tail != '\0') |
129 |
+ { |
130 |
+ /* Split audit list at colon. */ |
131 |
+ size_t len = strcspn (iter->audit_list_tail, ":"); |
132 |
+ if (len > 0 && len < PATH_MAX) |
133 |
+ { |
134 |
+ memcpy (iter->fname, iter->audit_list_tail, len); |
135 |
+ iter->fname[len] = '\0'; |
136 |
+ } |
137 |
+ else |
138 |
+ /* Do not return this name to the caller. */ |
139 |
+ iter->fname[0] = '\0'; |
140 |
+ |
141 |
+ /* Skip over the substring and the following delimiter. */ |
142 |
+ iter->audit_list_tail += len; |
143 |
+ if (*iter->audit_list_tail == ':') |
144 |
+ ++iter->audit_list_tail; |
145 |
+ |
146 |
+ /* If the name is valid, return it. */ |
147 |
+ if (dso_name_valid_for_suid (iter->fname)) |
148 |
+ return iter->fname; |
149 |
+ /* Otherwise, wrap around and try the next name. */ |
150 |
+ } |
151 |
+ /* Fall through to the procesing of audit_list. */ |
152 |
+ } |
153 |
+ |
154 |
+ if (iter->previous == NULL) |
155 |
+ { |
156 |
+ if (audit_list == NULL) |
157 |
+ /* No pre-parsed audit list. */ |
158 |
+ return NULL; |
159 |
+ /* Start of audit list. The first list element is at |
160 |
+ audit_list->next (cyclic list). */ |
161 |
+ iter->previous = audit_list->next; |
162 |
+ return iter->previous->name; |
163 |
+ } |
164 |
+ if (iter->previous == audit_list) |
165 |
+ /* Cyclic list wrap-around. */ |
166 |
+ return NULL; |
167 |
+ iter->previous = iter->previous->next; |
168 |
+ return iter->previous->name; |
169 |
+} |
170 |
+ |
171 |
#ifndef HAVE_INLINED_SYSCALLS |
172 |
/* Set nonzero during loading and initialization of executable and |
173 |
libraries, cleared before the executable's entry point runs. This |
174 |
@@ -1238,11 +1316,13 @@ of this helper program; chances are you did not intend to run this program.\n\ |
175 |
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); |
176 |
|
177 |
/* If we have auditing DSOs to load, do it now. */ |
178 |
- if (__glibc_unlikely (audit_list != NULL)) |
179 |
+ bool need_security_init = true; |
180 |
+ if (__glibc_unlikely (audit_list != NULL) |
181 |
+ || __glibc_unlikely (audit_list_string != NULL)) |
182 |
{ |
183 |
- /* Iterate over all entries in the list. The order is important. */ |
184 |
struct audit_ifaces *last_audit = NULL; |
185 |
- struct audit_list *al = audit_list->next; |
186 |
+ struct audit_list_iter al_iter; |
187 |
+ audit_list_iter_init (&al_iter); |
188 |
|
189 |
/* Since we start using the auditing DSOs right away we need to |
190 |
initialize the data structures now. */ |
191 |
@@ -1253,9 +1333,14 @@ of this helper program; chances are you did not intend to run this program.\n\ |
192 |
use different values (especially the pointer guard) and will |
193 |
fail later on. */ |
194 |
security_init (); |
195 |
+ need_security_init = false; |
196 |
|
197 |
- do |
198 |
+ while (true) |
199 |
{ |
200 |
+ const char *name = audit_list_iter_next (&al_iter); |
201 |
+ if (name == NULL) |
202 |
+ break; |
203 |
+ |
204 |
int tls_idx = GL(dl_tls_max_dtv_idx); |
205 |
|
206 |
/* Now it is time to determine the layout of the static TLS |
207 |
@@ -1264,7 +1349,7 @@ of this helper program; chances are you did not intend to run this program.\n\ |
208 |
no DF_STATIC_TLS bit is set. The reason is that we know |
209 |
glibc will use the static model. */ |
210 |
struct dlmopen_args dlmargs; |
211 |
- dlmargs.fname = al->name; |
212 |
+ dlmargs.fname = name; |
213 |
dlmargs.map = NULL; |
214 |
|
215 |
const char *objname; |
216 |
@@ -1277,7 +1362,7 @@ of this helper program; chances are you did not intend to run this program.\n\ |
217 |
not_loaded: |
218 |
_dl_error_printf ("\ |
219 |
ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
220 |
- al->name, err_str); |
221 |
+ name, err_str); |
222 |
if (malloced) |
223 |
free ((char *) err_str); |
224 |
} |
225 |
@@ -1381,10 +1466,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
226 |
goto not_loaded; |
227 |
} |
228 |
} |
229 |
- |
230 |
- al = al->next; |
231 |
} |
232 |
- while (al != audit_list->next); |
233 |
|
234 |
/* If we have any auditing modules, announce that we already |
235 |
have two objects loaded. */ |
236 |
@@ -1663,7 +1745,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
237 |
if (tcbp == NULL) |
238 |
tcbp = init_tls (); |
239 |
|
240 |
- if (__glibc_likely (audit_list == NULL)) |
241 |
+ if (__glibc_likely (need_security_init)) |
242 |
/* Initialize security features. But only if we have not done it |
243 |
earlier. */ |
244 |
security_init (); |
245 |
@@ -2294,9 +2376,7 @@ process_dl_audit (char *str) |
246 |
char *p; |
247 |
|
248 |
while ((p = (strsep) (&str, ":")) != NULL) |
249 |
- if (p[0] != '\0' |
250 |
- && (__builtin_expect (! __libc_enable_secure, 1) |
251 |
- || strchr (p, '/') == NULL)) |
252 |
+ if (dso_name_valid_for_suid (p)) |
253 |
{ |
254 |
/* This is using the local malloc, not the system malloc. The |
255 |
memory can never be freed. */ |
256 |
@@ -2360,7 +2440,7 @@ process_envvars (enum mode *modep) |
257 |
break; |
258 |
} |
259 |
if (memcmp (envline, "AUDIT", 5) == 0) |
260 |
- process_dl_audit (&envline[6]); |
261 |
+ audit_list_string = &envline[6]; |
262 |
break; |
263 |
|
264 |
case 7: |
265 |
|
266 |
|
267 |
|
268 |
1.1 src/patchsets/glibc/2.25/00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch |
269 |
|
270 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&view=markup |
271 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&content-type=text/plain |
272 |
|
273 |
Index: 00_all_0017-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch |
274 |
=================================================================== |
275 |
From 65ff0b7a085b85271ec8fde99f542281b495e3bc Mon Sep 17 00:00:00 2001 |
276 |
Message-Id: <65ff0b7a085b85271ec8fde99f542281b495e3bc.1495998948.git.fweimer@××××××.com> |
277 |
In-Reply-To: <cover.1495998948.git.fweimer@××××××.com> |
278 |
References: <cover.1495998948.git.fweimer@××××××.com> |
279 |
From: Florian Weimer <fweimer@××××××.com> |
280 |
Date: Sun, 28 May 2017 20:57:40 +0200 |
281 |
Subject: [PATCH 2/3] rtld: Reject overly long LD_PRELOAD path elements |
282 |
To: libc-alpha@××××××××××.org |
283 |
|
284 |
--- |
285 |
elf/rtld.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++--------------- |
286 |
1 file changed, 53 insertions(+), 16 deletions(-) |
287 |
|
288 |
diff --git a/elf/rtld.c b/elf/rtld.c |
289 |
index c9ddba1..7c049df 100644 |
290 |
--- a/elf/rtld.c |
291 |
+++ b/elf/rtld.c |
292 |
@@ -99,6 +99,22 @@ uintptr_t __pointer_chk_guard_local |
293 |
strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) |
294 |
#endif |
295 |
|
296 |
+/* Check that AT_SECURE=0, or that the passed name does not contain |
297 |
+ directories and is not overly long. Reject empty names |
298 |
+ unconditionally. */ |
299 |
+static bool |
300 |
+dso_name_valid_for_suid (const char *p) |
301 |
+{ |
302 |
+ if (__glibc_unlikely (__libc_enable_secure)) |
303 |
+ { |
304 |
+ /* Ignore pathnames with directories for AT_SECURE=1 |
305 |
+ programs, and also skip overlong names. */ |
306 |
+ size_t len = strlen (p); |
307 |
+ if (len >= NAME_MAX || memchr (p, '/', len) != NULL) |
308 |
+ return false; |
309 |
+ } |
310 |
+ return *p != '\0'; |
311 |
+} |
312 |
|
313 |
/* LD_AUDIT variable contents. Must be processed before the |
314 |
audit_list below. */ |
315 |
@@ -794,6 +810,42 @@ static const char *preloadlist attribute_relro; |
316 |
/* Nonzero if information about versions has to be printed. */ |
317 |
static int version_info attribute_relro; |
318 |
|
319 |
+/* The LD_PRELOAD environment variable gives list of libraries |
320 |
+ separated by white space or colons that are loaded before the |
321 |
+ executable's dependencies and prepended to the global scope list. |
322 |
+ (If the binary is running setuid all elements containing a '/' are |
323 |
+ ignored since it is insecure.) Return the number of preloads |
324 |
+ performed. */ |
325 |
+unsigned int |
326 |
+handle_ld_preload (const char *preloadlist, struct link_map *main_map) |
327 |
+{ |
328 |
+ unsigned int npreloads = 0; |
329 |
+ const char *p = preloadlist; |
330 |
+ char fname[PATH_MAX]; |
331 |
+ |
332 |
+ while (*p != '\0') |
333 |
+ { |
334 |
+ /* Split preload list at space/colon. */ |
335 |
+ size_t len = strcspn (p, " :"); |
336 |
+ if (len > 0 && len < PATH_MAX) |
337 |
+ { |
338 |
+ memcpy (fname, p, len); |
339 |
+ fname[len] = '\0'; |
340 |
+ } |
341 |
+ else |
342 |
+ fname[0] = '\0'; |
343 |
+ |
344 |
+ /* Skip over the substring and the following delimiter. */ |
345 |
+ p += len; |
346 |
+ if (*p == ' ' || *p == ':') |
347 |
+ ++p; |
348 |
+ |
349 |
+ if (dso_name_valid_for_suid (fname)) |
350 |
+ npreloads += do_preload (fname, main_map, "LD_PRELOAD"); |
351 |
+ } |
352 |
+ return npreloads; |
353 |
+} |
354 |
+ |
355 |
static void |
356 |
dl_main (const ElfW(Phdr) *phdr, |
357 |
ElfW(Word) phnum, |
358 |
@@ -1544,23 +1596,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
359 |
|
360 |
if (__glibc_unlikely (preloadlist != NULL)) |
361 |
{ |
362 |
- /* The LD_PRELOAD environment variable gives list of libraries |
363 |
- separated by white space or colons that are loaded before the |
364 |
- executable's dependencies and prepended to the global scope |
365 |
- list. If the binary is running setuid all elements |
366 |
- containing a '/' are ignored since it is insecure. */ |
367 |
- char *list = strdupa (preloadlist); |
368 |
- char *p; |
369 |
- |
370 |
HP_TIMING_NOW (start); |
371 |
- |
372 |
- /* Prevent optimizing strsep. Speed is not important here. */ |
373 |
- while ((p = (strsep) (&list, " :")) != NULL) |
374 |
- if (p[0] != '\0' |
375 |
- && (__builtin_expect (! __libc_enable_secure, 1) |
376 |
- || strchr (p, '/') == NULL)) |
377 |
- npreloads += do_preload (p, main_map, "LD_PRELOAD"); |
378 |
- |
379 |
+ npreloads += handle_ld_preload (preloadlist, main_map); |
380 |
HP_TIMING_NOW (stop); |
381 |
HP_TIMING_DIFF (diff, start, stop); |
382 |
HP_TIMING_ACCUM_NT (load_time, diff); |
383 |
|
384 |
|
385 |
|
386 |
1.1 src/patchsets/glibc/2.25/00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch |
387 |
|
388 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch?rev=1.1&view=markup |
389 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch?rev=1.1&content-type=text/plain |
390 |
|
391 |
Index: 00_all_0018-Add-IS_IN-guard-to-multiarch-IFUNC-implementations.patch |
392 |
=================================================================== |
393 |
From 862ee76acbf83a2d785809734b02c1929c4a0859 Mon Sep 17 00:00:00 2001 |
394 |
From: Matthias Maier <tamiko@××××.org> |
395 |
Date: Wed, 14 Jun 2017 03:22:11 -0500 |
396 |
Subject: [PATCH] Add IS_IN guard to multiarch/IFUNC implementations |
397 |
|
398 |
The two preceding rtld patches add the first reference to strcspn to |
399 |
ld.so, which pulls in the multiarch/IFUNC implementations because the |
400 |
files in question lack an IS_IN (libc) guard (which essentially disables |
401 |
IFUNCs in ld.so). |
402 |
|
403 |
Patch by Florian Weimer <fweimer@××××××.com> |
404 |
--- |
405 |
sysdeps/i386/i686/multiarch/strcspn-c.c | 6 ++++-- |
406 |
sysdeps/i386/i686/multiarch/varshift.c | 4 +++- |
407 |
2 files changed, 7 insertions(+), 3 deletions(-) |
408 |
|
409 |
diff --git a/sysdeps/i386/i686/multiarch/strcspn-c.c b/sysdeps/i386/i686/multiarch/strcspn-c.c |
410 |
index 6d61e19..ec230fb 100644 |
411 |
--- a/sysdeps/i386/i686/multiarch/strcspn-c.c |
412 |
+++ b/sysdeps/i386/i686/multiarch/strcspn-c.c |
413 |
@@ -1,2 +1,4 @@ |
414 |
-#define __strcspn_sse2 __strcspn_ia32 |
415 |
-#include <sysdeps/x86_64/multiarch/strcspn-c.c> |
416 |
+#if IS_IN (libc) |
417 |
+# define __strcspn_sse2 __strcspn_ia32 |
418 |
+# include <sysdeps/x86_64/multiarch/strcspn-c.c> |
419 |
+#endif |
420 |
diff --git a/sysdeps/i386/i686/multiarch/varshift.c b/sysdeps/i386/i686/multiarch/varshift.c |
421 |
index 7760b96..6742a35 100644 |
422 |
--- a/sysdeps/i386/i686/multiarch/varshift.c |
423 |
+++ b/sysdeps/i386/i686/multiarch/varshift.c |
424 |
@@ -1 +1,3 @@ |
425 |
-#include <sysdeps/x86_64/multiarch/varshift.c> |
426 |
+#if IS_IN (libc) |
427 |
+# include <sysdeps/x86_64/multiarch/varshift.c> |
428 |
+#endif |
429 |
-- |
430 |
2.13.0 |
431 |
|
432 |
|
433 |
|
434 |
|
435 |
1.1 src/patchsets/glibc/2.25/00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch |
436 |
|
437 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&view=markup |
438 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.25/00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&content-type=text/plain |
439 |
|
440 |
Index: 00_all_0019-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch |
441 |
=================================================================== |
442 |
From 1c1243b6fc33c029488add276e56570a07803bfd Mon Sep 17 00:00:00 2001 |
443 |
From: Siddhesh Poyarekar <siddhesh@××××××××××.org> |
444 |
Date: Tue, 7 Mar 2017 20:52:04 +0530 |
445 |
Subject: [PATCH] Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (bug |
446 |
#21209) |
447 |
|
448 |
The LD_HWCAP_MASK environment variable may alter the selection of |
449 |
function variants for some architectures. For AT_SECURE process it |
450 |
means that if an outdated routine has a bug that would otherwise not |
451 |
affect newer platforms by default, LD_HWCAP_MASK will allow that bug |
452 |
to be exploited. |
453 |
|
454 |
To be on the safe side, ignore and disable LD_HWCAP_MASK for setuid |
455 |
binaries. |
456 |
|
457 |
[BZ #21209] |
458 |
* elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for |
459 |
AT_SECURE processes. |
460 |
* sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK. |
461 |
* elf/tst-env-setuid.c (test_parent): Test LD_HWCAP_MASK. |
462 |
(test_child): Likewise. |
463 |
* elf/Makefile (tst-env-setuid-ENV): Add LD_HWCAP_MASK. |
464 |
--- |
465 |
ChangeLog | 10 ++++++++++ |
466 |
elf/Makefile | 3 ++- |
467 |
elf/rtld.c | 3 ++- |
468 |
elf/tst-env-setuid.c | 12 ++++++++++++ |
469 |
sysdeps/generic/unsecvars.h | 1 + |
470 |
5 files changed, 27 insertions(+), 2 deletions(-) |
471 |
|
472 |
diff --git a/elf/Makefile b/elf/Makefile |
473 |
index 61abeb59ee..cc4aeb25b6 100644 |
474 |
--- a/elf/Makefile |
475 |
+++ b/elf/Makefile |
476 |
@@ -1398,6 +1398,7 @@ $(objpfx)tst-nodelete-dlclose: $(objpfx)tst-nodelete-dlclose-dso.so |
477 |
$(objpfx)tst-nodelete-dlclose.out: $(objpfx)tst-nodelete-dlclose-dso.so \ |
478 |
$(objpfx)tst-nodelete-dlclose-plugin.so |
479 |
|
480 |
-tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 |
481 |
+tst-env-setuid-ENV = MALLOC_CHECK_=2 MALLOC_MMAP_THRESHOLD_=4096 \ |
482 |
+ LD_HWCAP_MASK=0xffffffff |
483 |
tst-env-setuid-tunables-ENV = \ |
484 |
GLIBC_TUNABLES=glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096 |
485 |
diff --git a/elf/rtld.c b/elf/rtld.c |
486 |
index a036ece956..5986eaf4a1 100644 |
487 |
--- a/elf/rtld.c |
488 |
+++ b/elf/rtld.c |
489 |
@@ -2404,7 +2404,8 @@ process_envvars (enum mode *modep) |
490 |
|
491 |
case 10: |
492 |
/* Mask for the important hardware capabilities. */ |
493 |
- if (memcmp (envline, "HWCAP_MASK", 10) == 0) |
494 |
+ if (!__libc_enable_secure |
495 |
+ && memcmp (envline, "HWCAP_MASK", 10) == 0) |
496 |
GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, |
497 |
0, 0); |
498 |
break; |
499 |
diff --git a/elf/tst-env-setuid.c b/elf/tst-env-setuid.c |
500 |
index 6ec3fa5874..eec408eb5d 100644 |
501 |
--- a/elf/tst-env-setuid.c |
502 |
+++ b/elf/tst-env-setuid.c |
503 |
@@ -213,6 +213,12 @@ test_child (void) |
504 |
return 1; |
505 |
} |
506 |
|
507 |
+ if (getenv ("LD_HWCAP_MASK") != NULL) |
508 |
+ { |
509 |
+ printf ("LD_HWCAP_MASK still set\n"); |
510 |
+ return 1; |
511 |
+ } |
512 |
+ |
513 |
return 0; |
514 |
} |
515 |
#endif |
516 |
@@ -233,6 +239,12 @@ test_parent (void) |
517 |
return 1; |
518 |
} |
519 |
|
520 |
+ if (getenv ("LD_HWCAP_MASK") == NULL) |
521 |
+ { |
522 |
+ printf ("LD_HWCAP_MASK lost\n"); |
523 |
+ return 1; |
524 |
+ } |
525 |
+ |
526 |
return 0; |
527 |
} |
528 |
#endif |
529 |
diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h |
530 |
index a74083786e..5ea8a4a259 100644 |
531 |
--- a/sysdeps/generic/unsecvars.h |
532 |
+++ b/sysdeps/generic/unsecvars.h |
533 |
@@ -16,6 +16,7 @@ |
534 |
"LD_DEBUG\0" \ |
535 |
"LD_DEBUG_OUTPUT\0" \ |
536 |
"LD_DYNAMIC_WEAK\0" \ |
537 |
+ "LD_HWCAP_MASK\0" \ |
538 |
"LD_LIBRARY_PATH\0" \ |
539 |
"LD_ORIGIN_PATH\0" \ |
540 |
"LD_PRELOAD\0" \ |
541 |
-- |
542 |
2.13.0 |