1 |
tamiko 17/06/19 16:43:43 |
2 |
|
3 |
Modified: README.history |
4 |
Added: |
5 |
00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch |
6 |
00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch |
7 |
00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch |
8 |
00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch |
9 |
00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch |
10 |
Log: |
11 |
glibc-2.23: update to patchset 8 |
12 |
|
13 |
Revision Changes Path |
14 |
1.9 src/patchsets/glibc/2.23/README.history |
15 |
|
16 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/README.history?rev=1.9&view=markup |
17 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/README.history?rev=1.9&content-type=text/plain |
18 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/README.history?r1=1.8&r2=1.9 |
19 |
|
20 |
Index: README.history |
21 |
=================================================================== |
22 |
RCS file: /var/cvsroot/gentoo/src/patchsets/glibc/2.23/README.history,v |
23 |
retrieving revision 1.8 |
24 |
retrieving revision 1.9 |
25 |
diff -u -r1.8 -r1.9 |
26 |
--- README.history 8 Dec 2016 19:28:34 -0000 1.8 |
27 |
+++ README.history 19 Jun 2017 16:43:43 -0000 1.9 |
28 |
@@ -1,3 +1,10 @@ |
29 |
+8 08 Jun 2017 |
30 |
+ + 00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch |
31 |
+ + 00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch |
32 |
+ + 00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch |
33 |
+ + 00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch |
34 |
+ + 00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch |
35 |
+ |
36 |
7 08 Dec 2016 |
37 |
+ 00_all_0090-MIPS-Add-.insn-to-ensure-a-text-label-is-defined-as-.patch |
38 |
+ 00_all_0091-alpha-fix-ceil-on-sNaN-input.patch |
39 |
|
40 |
|
41 |
|
42 |
1.1 src/patchsets/glibc/2.23/00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch |
43 |
|
44 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&view=markup |
45 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&content-type=text/plain |
46 |
|
47 |
Index: 00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch |
48 |
=================================================================== |
49 |
From 4d009d39ac9ede0369e268554a181b428f177a80 Mon Sep 17 00:00:00 2001 |
50 |
Message-Id: <4d009d39ac9ede0369e268554a181b428f177a80.1495998948.git.fweimer@××××××.com> |
51 |
In-Reply-To: <cover.1495998948.git.fweimer@××××××.com> |
52 |
References: <cover.1495998948.git.fweimer@××××××.com> |
53 |
From: Florian Weimer <fweimer@××××××.com> |
54 |
Date: Sun, 28 May 2017 20:37:40 +0200 |
55 |
Subject: [PATCH 1/3] rtld: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1 |
56 |
programs |
57 |
To: libc-alpha@××××××××××.org |
58 |
|
59 |
LD_LIBRARY_PATH can only be used to reorder system search paths, which |
60 |
is not useful functionality. |
61 |
--- |
62 |
elf/rtld.c | 3 ++- |
63 |
1 file changed, 2 insertions(+), 1 deletion(-) |
64 |
|
65 |
diff --git a/elf/rtld.c b/elf/rtld.c |
66 |
index 319ef06..824b6cf 100644 |
67 |
--- a/elf/rtld.c |
68 |
+++ b/elf/rtld.c |
69 |
@@ -2419,7 +2419,8 @@ process_envvars (enum mode *modep) |
70 |
|
71 |
case 12: |
72 |
/* The library search path. */ |
73 |
- if (memcmp (envline, "LIBRARY_PATH", 12) == 0) |
74 |
+ if (!__libc_enable_secure |
75 |
+ && memcmp (envline, "LIBRARY_PATH", 12) == 0) |
76 |
{ |
77 |
library_path = &envline[13]; |
78 |
break; |
79 |
-- |
80 |
2.9.4 |
81 |
|
82 |
|
83 |
|
84 |
|
85 |
1.1 src/patchsets/glibc/2.23/00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch |
86 |
|
87 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&view=markup |
88 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&content-type=text/plain |
89 |
|
90 |
Index: 00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch |
91 |
=================================================================== |
92 |
From ba67ba3275d47e0080f0e5f09d9f5102c000c97e Mon Sep 17 00:00:00 2001 |
93 |
Message-Id: <ba67ba3275d47e0080f0e5f09d9f5102c000c97e.1495998948.git.fweimer@××××××.com> |
94 |
In-Reply-To: <cover.1495998948.git.fweimer@××××××.com> |
95 |
References: <cover.1495998948.git.fweimer@××××××.com> |
96 |
From: Florian Weimer <fweimer@××××××.com> |
97 |
Date: Sun, 28 May 2017 20:44:52 +0200 |
98 |
Subject: [PATCH 3/3] rtld: Reject overly long LD_AUDIT path elements |
99 |
To: libc-alpha@××××××××××.org |
100 |
|
101 |
Also only process the last LD_AUDIT entry. |
102 |
--- |
103 |
elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
104 |
1 file changed, 95 insertions(+), 15 deletions(-) |
105 |
|
106 |
diff --git a/elf/rtld.c b/elf/rtld.c |
107 |
index 215a9ae..511c6bf 100644 |
108 |
--- a/elf/rtld.c |
109 |
+++ b/elf/rtld.c |
110 |
@@ -100,13 +100,91 @@ strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) |
111 |
#endif |
112 |
|
113 |
|
114 |
-/* List of auditing DSOs. */ |
115 |
+/* LD_AUDIT variable contents. Must be processed before the |
116 |
+ audit_list below. */ |
117 |
+const char *audit_list_string; |
118 |
+ |
119 |
+/* Cyclic list of auditing DSOs. audit_list->next is the first |
120 |
+ element. */ |
121 |
static struct audit_list |
122 |
{ |
123 |
const char *name; |
124 |
struct audit_list *next; |
125 |
} *audit_list; |
126 |
|
127 |
+/* Iterator for audit_list_string followed by audit_list. */ |
128 |
+struct audit_list_iter |
129 |
+{ |
130 |
+ /* Tail of audit_list_string still needing processing, or NULL. */ |
131 |
+ const char *audit_list_tail; |
132 |
+ |
133 |
+ /* The list element returned in the previous iteration. NULL before |
134 |
+ the first element. */ |
135 |
+ struct audit_list *previous; |
136 |
+ |
137 |
+ /* Scratch buffer for returning a name which is part of |
138 |
+ audit_list_string. */ |
139 |
+ char fname[PATH_MAX]; |
140 |
+}; |
141 |
+ |
142 |
+/* Initialize an audit list iterator. */ |
143 |
+static void |
144 |
+audit_list_iter_init (struct audit_list_iter *iter) |
145 |
+{ |
146 |
+ iter->audit_list_tail = audit_list_string; |
147 |
+ iter->previous = NULL; |
148 |
+} |
149 |
+ |
150 |
+/* Iterate through both audit_list_string and audit_list. */ |
151 |
+static const char * |
152 |
+audit_list_iter_next (struct audit_list_iter *iter) |
153 |
+{ |
154 |
+ if (iter->audit_list_tail != NULL) |
155 |
+ { |
156 |
+ /* First iterate over audit_list_string. */ |
157 |
+ while (*iter->audit_list_tail != '\0') |
158 |
+ { |
159 |
+ /* Split audit list at colon. */ |
160 |
+ size_t len = strcspn (iter->audit_list_tail, ":"); |
161 |
+ if (len > 0 && len < PATH_MAX) |
162 |
+ { |
163 |
+ memcpy (iter->fname, iter->audit_list_tail, len); |
164 |
+ iter->fname[len] = '\0'; |
165 |
+ } |
166 |
+ else |
167 |
+ /* Do not return this name to the caller. */ |
168 |
+ iter->fname[0] = '\0'; |
169 |
+ |
170 |
+ /* Skip over the substring and the following delimiter. */ |
171 |
+ iter->audit_list_tail += len; |
172 |
+ if (*iter->audit_list_tail == ':') |
173 |
+ ++iter->audit_list_tail; |
174 |
+ |
175 |
+ /* If the name is valid, return it. */ |
176 |
+ if (dso_name_valid_for_suid (iter->fname)) |
177 |
+ return iter->fname; |
178 |
+ /* Otherwise, wrap around and try the next name. */ |
179 |
+ } |
180 |
+ /* Fall through to the procesing of audit_list. */ |
181 |
+ } |
182 |
+ |
183 |
+ if (iter->previous == NULL) |
184 |
+ { |
185 |
+ if (audit_list == NULL) |
186 |
+ /* No pre-parsed audit list. */ |
187 |
+ return NULL; |
188 |
+ /* Start of audit list. The first list element is at |
189 |
+ audit_list->next (cyclic list). */ |
190 |
+ iter->previous = audit_list->next; |
191 |
+ return iter->previous->name; |
192 |
+ } |
193 |
+ if (iter->previous == audit_list) |
194 |
+ /* Cyclic list wrap-around. */ |
195 |
+ return NULL; |
196 |
+ iter->previous = iter->previous->next; |
197 |
+ return iter->previous->name; |
198 |
+} |
199 |
+ |
200 |
#ifndef HAVE_INLINED_SYSCALLS |
201 |
/* Set nonzero during loading and initialization of executable and |
202 |
libraries, cleared before the executable's entry point runs. This |
203 |
@@ -1257,11 +1335,13 @@ of this helper program; chances are you did not intend to run this program.\n\ |
204 |
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); |
205 |
|
206 |
/* If we have auditing DSOs to load, do it now. */ |
207 |
- if (__glibc_unlikely (audit_list != NULL)) |
208 |
+ bool need_security_init = true; |
209 |
+ if (__glibc_unlikely (audit_list != NULL) |
210 |
+ || __glibc_unlikely (audit_list_string != NULL)) |
211 |
{ |
212 |
- /* Iterate over all entries in the list. The order is important. */ |
213 |
struct audit_ifaces *last_audit = NULL; |
214 |
- struct audit_list *al = audit_list->next; |
215 |
+ struct audit_list_iter al_iter; |
216 |
+ audit_list_iter_init (&al_iter); |
217 |
|
218 |
/* Since we start using the auditing DSOs right away we need to |
219 |
initialize the data structures now. */ |
220 |
@@ -1272,9 +1352,14 @@ of this helper program; chances are you did not intend to run this program.\n\ |
221 |
use different values (especially the pointer guard) and will |
222 |
fail later on. */ |
223 |
security_init (); |
224 |
+ need_security_init = false; |
225 |
|
226 |
- do |
227 |
+ while (true) |
228 |
{ |
229 |
+ const char *name = audit_list_iter_next (&al_iter); |
230 |
+ if (name == NULL) |
231 |
+ break; |
232 |
+ |
233 |
int tls_idx = GL(dl_tls_max_dtv_idx); |
234 |
|
235 |
/* Now it is time to determine the layout of the static TLS |
236 |
@@ -1283,7 +1368,7 @@ of this helper program; chances are you did not intend to run this program.\n\ |
237 |
no DF_STATIC_TLS bit is set. The reason is that we know |
238 |
glibc will use the static model. */ |
239 |
struct dlmopen_args dlmargs; |
240 |
- dlmargs.fname = al->name; |
241 |
+ dlmargs.fname = name; |
242 |
dlmargs.map = NULL; |
243 |
|
244 |
const char *objname; |
245 |
@@ -1296,7 +1381,7 @@ of this helper program; chances are you did not intend to run this program.\n\ |
246 |
not_loaded: |
247 |
_dl_error_printf ("\ |
248 |
ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
249 |
- al->name, err_str); |
250 |
+ name, err_str); |
251 |
if (malloced) |
252 |
free ((char *) err_str); |
253 |
} |
254 |
@@ -1400,10 +1485,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
255 |
goto not_loaded; |
256 |
} |
257 |
} |
258 |
- |
259 |
- al = al->next; |
260 |
} |
261 |
- while (al != audit_list->next); |
262 |
|
263 |
/* If we have any auditing modules, announce that we already |
264 |
have two objects loaded. */ |
265 |
@@ -1682,7 +1764,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
266 |
if (tcbp == NULL) |
267 |
tcbp = init_tls (); |
268 |
|
269 |
- if (__glibc_likely (audit_list == NULL)) |
270 |
+ if (__glibc_likely (need_security_init)) |
271 |
/* Initialize security features. But only if we have not done it |
272 |
earlier. */ |
273 |
security_init (); |
274 |
@@ -2313,9 +2395,7 @@ process_dl_audit (char *str) |
275 |
char *p; |
276 |
|
277 |
while ((p = (strsep) (&str, ":")) != NULL) |
278 |
- if (p[0] != '\0' |
279 |
- && (__builtin_expect (! __libc_enable_secure, 1) |
280 |
- || strchr (p, '/') == NULL)) |
281 |
+ if (dso_name_valid_for_suid (p)) |
282 |
{ |
283 |
/* This is using the local malloc, not the system malloc. The |
284 |
memory can never be freed. */ |
285 |
@@ -2379,7 +2459,7 @@ process_envvars (enum mode *modep) |
286 |
break; |
287 |
} |
288 |
if (memcmp (envline, "AUDIT", 5) == 0) |
289 |
- process_dl_audit (&envline[6]); |
290 |
+ audit_list_string = &envline[6]; |
291 |
break; |
292 |
|
293 |
case 7: |
294 |
|
295 |
|
296 |
|
297 |
1.1 src/patchsets/glibc/2.23/00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch |
298 |
|
299 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&view=markup |
300 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&content-type=text/plain |
301 |
|
302 |
Index: 00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch |
303 |
=================================================================== |
304 |
From 65ff0b7a085b85271ec8fde99f542281b495e3bc Mon Sep 17 00:00:00 2001 |
305 |
Message-Id: <65ff0b7a085b85271ec8fde99f542281b495e3bc.1495998948.git.fweimer@××××××.com> |
306 |
In-Reply-To: <cover.1495998948.git.fweimer@××××××.com> |
307 |
References: <cover.1495998948.git.fweimer@××××××.com> |
308 |
From: Florian Weimer <fweimer@××××××.com> |
309 |
Date: Sun, 28 May 2017 20:57:40 +0200 |
310 |
Subject: [PATCH 2/3] rtld: Reject overly long LD_PRELOAD path elements |
311 |
To: libc-alpha@××××××××××.org |
312 |
|
313 |
--- |
314 |
elf/rtld.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++--------------- |
315 |
1 file changed, 53 insertions(+), 16 deletions(-) |
316 |
|
317 |
diff --git a/elf/rtld.c b/elf/rtld.c |
318 |
index 215a9ae..8c41cc9 100644 |
319 |
--- a/elf/rtld.c |
320 |
+++ b/elf/rtld.c |
321 |
@@ -99,6 +99,22 @@ uintptr_t __pointer_chk_guard_local |
322 |
strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) |
323 |
#endif |
324 |
|
325 |
+/* Check that AT_SECURE=0, or that the passed name does not contain |
326 |
+ directories and is not overly long. Reject empty names |
327 |
+ unconditionally. */ |
328 |
+static bool |
329 |
+dso_name_valid_for_suid (const char *p) |
330 |
+{ |
331 |
+ if (__glibc_unlikely (__libc_enable_secure)) |
332 |
+ { |
333 |
+ /* Ignore pathnames with directories for AT_SECURE=1 |
334 |
+ programs, and also skip overlong names. */ |
335 |
+ size_t len = strlen (p); |
336 |
+ if (len >= NAME_MAX || memchr (p, '/', len) != NULL) |
337 |
+ return false; |
338 |
+ } |
339 |
+ return *p != '\0'; |
340 |
+} |
341 |
|
342 |
/* List of auditing DSOs. */ |
343 |
static struct audit_list |
344 |
@@ -730,6 +746,42 @@ static const char *preloadlist attribute_relro; |
345 |
/* Nonzero if information about versions has to be printed. */ |
346 |
static int version_info attribute_relro; |
347 |
|
348 |
+/* The LD_PRELOAD environment variable gives list of libraries |
349 |
+ separated by white space or colons that are loaded before the |
350 |
+ executable's dependencies and prepended to the global scope list. |
351 |
+ (If the binary is running setuid all elements containing a '/' are |
352 |
+ ignored since it is insecure.) Return the number of preloads |
353 |
+ performed. */ |
354 |
+unsigned int |
355 |
+handle_ld_preload (const char *preloadlist, struct link_map *main_map) |
356 |
+{ |
357 |
+ unsigned int npreloads = 0; |
358 |
+ const char *p = preloadlist; |
359 |
+ char fname[PATH_MAX]; |
360 |
+ |
361 |
+ while (*p != '\0') |
362 |
+ { |
363 |
+ /* Split preload list at space/colon. */ |
364 |
+ size_t len = strcspn (p, " :"); |
365 |
+ if (len > 0 && len < PATH_MAX) |
366 |
+ { |
367 |
+ memcpy (fname, p, len); |
368 |
+ fname[len] = '\0'; |
369 |
+ } |
370 |
+ else |
371 |
+ fname[0] = '\0'; |
372 |
+ |
373 |
+ /* Skip over the substring and the following delimiter. */ |
374 |
+ p += len; |
375 |
+ if (*p == ' ' || *p == ':') |
376 |
+ ++p; |
377 |
+ |
378 |
+ if (dso_name_valid_for_suid (fname)) |
379 |
+ npreloads += do_preload (fname, main_map, "LD_PRELOAD"); |
380 |
+ } |
381 |
+ return npreloads; |
382 |
+} |
383 |
+ |
384 |
static void |
385 |
dl_main (const ElfW(Phdr) *phdr, |
386 |
ElfW(Word) phnum, |
387 |
@@ -1481,23 +1533,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", |
388 |
|
389 |
if (__glibc_unlikely (preloadlist != NULL)) |
390 |
{ |
391 |
- /* The LD_PRELOAD environment variable gives list of libraries |
392 |
- separated by white space or colons that are loaded before the |
393 |
- executable's dependencies and prepended to the global scope |
394 |
- list. If the binary is running setuid all elements |
395 |
- containing a '/' are ignored since it is insecure. */ |
396 |
- char *list = strdupa (preloadlist); |
397 |
- char *p; |
398 |
- |
399 |
HP_TIMING_NOW (start); |
400 |
- |
401 |
- /* Prevent optimizing strsep. Speed is not important here. */ |
402 |
- while ((p = (strsep) (&list, " :")) != NULL) |
403 |
- if (p[0] != '\0' |
404 |
- && (__builtin_expect (! __libc_enable_secure, 1) |
405 |
- || strchr (p, '/') == NULL)) |
406 |
- npreloads += do_preload (p, main_map, "LD_PRELOAD"); |
407 |
- |
408 |
+ npreloads += handle_ld_preload (preloadlist, main_map); |
409 |
HP_TIMING_NOW (stop); |
410 |
HP_TIMING_DIFF (diff, start, stop); |
411 |
HP_TIMING_ACCUM_NT (load_time, diff); |
412 |
|
413 |
|
414 |
|
415 |
1.1 src/patchsets/glibc/2.23/00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch |
416 |
|
417 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&view=markup |
418 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&content-type=text/plain |
419 |
|
420 |
Index: 00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch |
421 |
=================================================================== |
422 |
From 1c1243b6fc33c029488add276e56570a07803bfd Mon Sep 17 00:00:00 2001 |
423 |
From: Siddhesh Poyarekar <siddhesh@××××××××××.org> |
424 |
Date: Tue, 7 Mar 2017 20:52:04 +0530 |
425 |
Subject: [PATCH] Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (bug |
426 |
#21209) |
427 |
|
428 |
The LD_HWCAP_MASK environment variable may alter the selection of |
429 |
function variants for some architectures. For AT_SECURE process it |
430 |
means that if an outdated routine has a bug that would otherwise not |
431 |
affect newer platforms by default, LD_HWCAP_MASK will allow that bug |
432 |
to be exploited. |
433 |
|
434 |
To be on the safe side, ignore and disable LD_HWCAP_MASK for setuid |
435 |
binaries. |
436 |
|
437 |
[BZ #21209] |
438 |
* elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for |
439 |
AT_SECURE processes. |
440 |
* sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK. |
441 |
* elf/tst-env-setuid.c (test_parent): Test LD_HWCAP_MASK. |
442 |
(test_child): Likewise. |
443 |
* elf/Makefile (tst-env-setuid-ENV): Add LD_HWCAP_MASK. |
444 |
--- |
445 |
ChangeLog | 10 ++++++++++ |
446 |
elf/Makefile | 3 ++- |
447 |
elf/rtld.c | 3 ++- |
448 |
elf/tst-env-setuid.c | 12 ++++++++++++ |
449 |
sysdeps/generic/unsecvars.h | 1 + |
450 |
5 files changed, 27 insertions(+), 2 deletions(-) |
451 |
|
452 |
diff --git a/elf/rtld.c b/elf/rtld.c |
453 |
index a036ece956..5986eaf4a1 100644 |
454 |
--- a/elf/rtld.c |
455 |
+++ b/elf/rtld.c |
456 |
@@ -2404,7 +2404,8 @@ process_envvars (enum mode *modep) |
457 |
|
458 |
case 10: |
459 |
/* Mask for the important hardware capabilities. */ |
460 |
- if (memcmp (envline, "HWCAP_MASK", 10) == 0) |
461 |
+ if (!__libc_enable_secure |
462 |
+ && memcmp (envline, "HWCAP_MASK", 10) == 0) |
463 |
GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, |
464 |
0, 0); |
465 |
break; |
466 |
diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h |
467 |
index a74083786e..5ea8a4a259 100644 |
468 |
--- a/sysdeps/generic/unsecvars.h |
469 |
+++ b/sysdeps/generic/unsecvars.h |
470 |
@@ -16,6 +16,7 @@ |
471 |
"LD_DEBUG\0" \ |
472 |
"LD_DEBUG_OUTPUT\0" \ |
473 |
"LD_DYNAMIC_WEAK\0" \ |
474 |
+ "LD_HWCAP_MASK\0" \ |
475 |
"LD_LIBRARY_PATH\0" \ |
476 |
"LD_ORIGIN_PATH\0" \ |
477 |
"LD_PRELOAD\0" \ |
478 |
-- |
479 |
2.13.0 |
480 |
|
481 |
|
482 |
|
483 |
|
484 |
1.1 src/patchsets/glibc/2.23/00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch |
485 |
|
486 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch?rev=1.1&view=markup |
487 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch?rev=1.1&content-type=text/plain |
488 |
|
489 |
Index: 00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch |
490 |
=================================================================== |
491 |
From 20f534e0abd81149c71cef082c8c058bb9d953af Mon Sep 17 00:00:00 2001 |
492 |
From: Florian Weimer <fweimer@××××××.com> |
493 |
Date: Sat, 31 Dec 2016 20:22:09 +0100 |
494 |
Subject: [PATCH] CVE-2015-5180: resolv: Fix crash with internal QTYPE [BZ |
495 |
#18784] |
496 |
|
497 |
Also rename T_UNSPEC because an upcoming public header file |
498 |
update will use that name. |
499 |
|
500 |
(cherry picked from commit fc82b0a2dfe7dbd35671c10510a8da1043d746a5) |
501 |
(cherry picked from commit b3b37f1a5559a7620e31c8053ed1b44f798f2b6d) |
502 |
--- |
503 |
include/arpa/nameser_compat.h | 6 +- |
504 |
resolv/Makefile | 5 ++ |
505 |
resolv/nss_dns/dns-host.c | 2 +- |
506 |
resolv/res_mkquery.c | 4 + |
507 |
resolv/res_query.c | 6 +- |
508 |
resolv/tst-resolv-qtypes.c | 185 ++++++++++++++++++++++++++++++++++++++++++ |
509 |
6 files changed, 201 insertions(+), 7 deletions(-) |
510 |
create mode 100644 resolv/tst-resolv-qtypes.c |
511 |
|
512 |
diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h |
513 |
index 2e735ede4c0e..7c0deed9aed4 100644 |
514 |
--- a/include/arpa/nameser_compat.h |
515 |
+++ b/include/arpa/nameser_compat.h |
516 |
@@ -1,8 +1,8 @@ |
517 |
#ifndef _ARPA_NAMESER_COMPAT_ |
518 |
#include <resolv/arpa/nameser_compat.h> |
519 |
|
520 |
-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e., |
521 |
- T_A and T_AAAA). */ |
522 |
-#define T_UNSPEC 62321 |
523 |
+/* The number is outside the 16-bit RR type range and is used |
524 |
+ internally by the implementation. */ |
525 |
+#define T_QUERY_A_AND_AAAA 439963904 |
526 |
|
527 |
#endif |
528 |
diff --git a/resolv/Makefile b/resolv/Makefile |
529 |
index 8be41d3ae141..a4c86b976257 100644 |
530 |
--- a/resolv/Makefile |
531 |
+++ b/resolv/Makefile |
532 |
@@ -40,6 +40,9 @@ ifeq ($(have-thread-library),yes) |
533 |
extra-libs += libanl |
534 |
routines += gai_sigqueue |
535 |
tests += tst-res_hconf_reorder |
536 |
+ |
537 |
+# This test sends millions of packets and is rather slow. |
538 |
+xtests += tst-resolv-qtypes |
539 |
endif |
540 |
extra-libs-others = $(extra-libs) |
541 |
libresolv-routines := gethnamaddr res_comp res_debug \ |
542 |
@@ -117,3 +120,5 @@ tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace |
543 |
$(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out |
544 |
$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \ |
545 |
$(evaluate-test) |
546 |
+ |
547 |
+$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) |
548 |
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c |
549 |
index 5f9e35701b2a..d16fa4b8edf6 100644 |
550 |
--- a/resolv/nss_dns/dns-host.c |
551 |
+++ b/resolv/nss_dns/dns-host.c |
552 |
@@ -323,7 +323,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, |
553 |
|
554 |
int olderr = errno; |
555 |
enum nss_status status; |
556 |
- int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, |
557 |
+ int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA, |
558 |
host_buffer.buf->buf, 2048, &host_buffer.ptr, |
559 |
&ans2p, &nans2p, &resplen2, &ans2p_malloced); |
560 |
if (n >= 0) |
561 |
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c |
562 |
index 12f9730199f8..d80b5318e5e0 100644 |
563 |
--- a/resolv/res_mkquery.c |
564 |
+++ b/resolv/res_mkquery.c |
565 |
@@ -103,6 +103,10 @@ res_nmkquery(res_state statp, |
566 |
int n; |
567 |
u_char *dnptrs[20], **dpp, **lastdnptr; |
568 |
|
569 |
+ if (class < 0 || class > 65535 |
570 |
+ || type < 0 || type > 65535) |
571 |
+ return -1; |
572 |
+ |
573 |
#ifdef DEBUG |
574 |
if (statp->options & RES_DEBUG) |
575 |
printf(";; res_nmkquery(%s, %s, %s, %s)\n", |
576 |
diff --git a/resolv/res_query.c b/resolv/res_query.c |
577 |
index 944d1a90f57e..07dc6f658386 100644 |
578 |
--- a/resolv/res_query.c |
579 |
+++ b/resolv/res_query.c |
580 |
@@ -122,7 +122,7 @@ __libc_res_nquery(res_state statp, |
581 |
int n, use_malloc = 0; |
582 |
u_int oflags = statp->_flags; |
583 |
|
584 |
- size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE; |
585 |
+ size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE; |
586 |
u_char *buf = alloca (bufsize); |
587 |
u_char *query1 = buf; |
588 |
int nquery1 = -1; |
589 |
@@ -137,7 +137,7 @@ __libc_res_nquery(res_state statp, |
590 |
printf(";; res_query(%s, %d, %d)\n", name, class, type); |
591 |
#endif |
592 |
|
593 |
- if (type == T_UNSPEC) |
594 |
+ if (type == T_QUERY_A_AND_AAAA) |
595 |
{ |
596 |
n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL, |
597 |
query1, bufsize); |
598 |
@@ -190,7 +190,7 @@ __libc_res_nquery(res_state statp, |
599 |
if (__builtin_expect (n <= 0, 0) && !use_malloc) { |
600 |
/* Retry just in case res_nmkquery failed because of too |
601 |
short buffer. Shouldn't happen. */ |
602 |
- bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET; |
603 |
+ bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET; |
604 |
buf = malloc (bufsize); |
605 |
if (buf != NULL) { |
606 |
query1 = buf; |
607 |
diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c |
608 |
new file mode 100644 |
609 |
index 000000000000..b3e60c693bf2 |
610 |
--- /dev/null |
611 |
+++ b/resolv/tst-resolv-qtypes.c |
612 |
@@ -0,0 +1,185 @@ |
613 |
+/* Exercise low-level query functions with different QTYPEs. |
614 |
+ Copyright (C) 2016 Free Software Foundation, Inc. |
615 |
+ This file is part of the GNU C Library. |
616 |
+ |
617 |
+ The GNU C Library is free software; you can redistribute it and/or |
618 |
+ modify it under the terms of the GNU Lesser General Public |
619 |
+ License as published by the Free Software Foundation; either |
620 |
+ version 2.1 of the License, or (at your option) any later version. |
621 |
+ |
622 |
+ The GNU C Library is distributed in the hope that it will be useful, |
623 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
624 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
625 |
+ Lesser General Public License for more details. |
626 |
+ |
627 |
+ You should have received a copy of the GNU Lesser General Public |
628 |
+ License along with the GNU C Library; if not, see |
629 |
+ <http://www.gnu.org/licenses/>. */ |
630 |
+ |
631 |
+#include <resolv.h> |
632 |
+#include <string.h> |
633 |
+#include <support/check.h> |
634 |
+#include <support/check_nss.h> |
635 |
+#include <support/resolv_test.h> |
636 |
+#include <support/support.h> |
637 |
+#include <support/test-driver.h> |
638 |
+#include <support/xmemstream.h> |
639 |
+ |
640 |
+/* If ture, the response function will send the actual response packet |
641 |
+ over TCP instead of UDP. */ |
642 |
+static volatile bool force_tcp; |
643 |
+ |
644 |
+/* Send back a fake resource record matching the QTYPE. */ |
645 |
+static void |
646 |
+response (const struct resolv_response_context *ctx, |
647 |
+ struct resolv_response_builder *b, |
648 |
+ const char *qname, uint16_t qclass, uint16_t qtype) |
649 |
+{ |
650 |
+ if (force_tcp && ctx->tcp) |
651 |
+ { |
652 |
+ resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 }); |
653 |
+ resolv_response_add_question (b, qname, qclass, qtype); |
654 |
+ return; |
655 |
+ } |
656 |
+ |
657 |
+ resolv_response_init (b, (struct resolv_response_flags) { }); |
658 |
+ resolv_response_add_question (b, qname, qclass, qtype); |
659 |
+ resolv_response_section (b, ns_s_an); |
660 |
+ resolv_response_open_record (b, qname, qclass, qtype, 0); |
661 |
+ resolv_response_add_data (b, &qtype, sizeof (qtype)); |
662 |
+ resolv_response_close_record (b); |
663 |
+} |
664 |
+ |
665 |
+static const const char *domain = "www.example.com"; |
666 |
+ |
667 |
+static int |
668 |
+wrap_res_query (int type, unsigned char *answer, int answer_length) |
669 |
+{ |
670 |
+ return res_query (domain, C_IN, type, answer, answer_length); |
671 |
+} |
672 |
+ |
673 |
+static int |
674 |
+wrap_res_search (int type, unsigned char *answer, int answer_length) |
675 |
+{ |
676 |
+ return res_query (domain, C_IN, type, answer, answer_length); |
677 |
+} |
678 |
+ |
679 |
+static int |
680 |
+wrap_res_querydomain (int type, unsigned char *answer, int answer_length) |
681 |
+{ |
682 |
+ return res_querydomain ("www", "example.com", C_IN, type, |
683 |
+ answer, answer_length); |
684 |
+} |
685 |
+ |
686 |
+static int |
687 |
+wrap_res_send (int type, unsigned char *answer, int answer_length) |
688 |
+{ |
689 |
+ unsigned char buf[512]; |
690 |
+ int ret = res_mkquery (QUERY, domain, C_IN, type, |
691 |
+ (const unsigned char *) "", 0, NULL, |
692 |
+ buf, sizeof (buf)); |
693 |
+ if (type < 0 || type >= 65536) |
694 |
+ { |
695 |
+ /* res_mkquery fails for out-of-range record types. */ |
696 |
+ TEST_VERIFY_EXIT (ret == -1); |
697 |
+ return -1; |
698 |
+ } |
699 |
+ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ |
700 |
+ return res_send (buf, ret, answer, answer_length); |
701 |
+} |
702 |
+ |
703 |
+static int |
704 |
+wrap_res_nquery (int type, unsigned char *answer, int answer_length) |
705 |
+{ |
706 |
+ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); |
707 |
+} |
708 |
+ |
709 |
+static int |
710 |
+wrap_res_nsearch (int type, unsigned char *answer, int answer_length) |
711 |
+{ |
712 |
+ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); |
713 |
+} |
714 |
+ |
715 |
+static int |
716 |
+wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length) |
717 |
+{ |
718 |
+ return res_nquerydomain (&_res, "www", "example.com", C_IN, type, |
719 |
+ answer, answer_length); |
720 |
+} |
721 |
+ |
722 |
+static int |
723 |
+wrap_res_nsend (int type, unsigned char *answer, int answer_length) |
724 |
+{ |
725 |
+ unsigned char buf[512]; |
726 |
+ int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type, |
727 |
+ (const unsigned char *) "", 0, NULL, |
728 |
+ buf, sizeof (buf)); |
729 |
+ if (type < 0 || type >= 65536) |
730 |
+ { |
731 |
+ /* res_mkquery fails for out-of-range record types. */ |
732 |
+ TEST_VERIFY_EXIT (ret == -1); |
733 |
+ return -1; |
734 |
+ } |
735 |
+ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ |
736 |
+ return res_nsend (&_res, buf, ret, answer, answer_length); |
737 |
+} |
738 |
+ |
739 |
+static void |
740 |
+test_function (const char *fname, |
741 |
+ int (*func) (int type, |
742 |
+ unsigned char *answer, int answer_length)) |
743 |
+{ |
744 |
+ unsigned char buf[512]; |
745 |
+ for (int tcp = 0; tcp < 2; ++tcp) |
746 |
+ { |
747 |
+ force_tcp = tcp; |
748 |
+ for (unsigned int type = 1; type <= 65535; ++type) |
749 |
+ { |
750 |
+ if (test_verbose) |
751 |
+ printf ("info: sending QTYPE %d with %s (tcp=%d)\n", |
752 |
+ type, fname, tcp); |
753 |
+ int ret = func (type, buf, sizeof (buf)); |
754 |
+ if (ret != 47) |
755 |
+ FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d", |
756 |
+ fname,tcp, type, ret); |
757 |
+ /* One question, one answer record. */ |
758 |
+ TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0); |
759 |
+ /* Question section. */ |
760 |
+ static const char qname[] = "\3www\7example\3com"; |
761 |
+ size_t qname_length = sizeof (qname); |
762 |
+ TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0); |
763 |
+ /* RDATA part of answer. */ |
764 |
+ uint16_t type16 = type; |
765 |
+ TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0); |
766 |
+ } |
767 |
+ } |
768 |
+ |
769 |
+ TEST_VERIFY (func (-1, buf, sizeof (buf) == -1)); |
770 |
+ TEST_VERIFY (func (65536, buf, sizeof (buf) == -1)); |
771 |
+} |
772 |
+ |
773 |
+static int |
774 |
+do_test (void) |
775 |
+{ |
776 |
+ struct resolv_redirect_config config = |
777 |
+ { |
778 |
+ .response_callback = response, |
779 |
+ }; |
780 |
+ struct resolv_test *obj = resolv_test_start (config); |
781 |
+ |
782 |
+ test_function ("res_query", &wrap_res_query); |
783 |
+ test_function ("res_search", &wrap_res_search); |
784 |
+ test_function ("res_querydomain", &wrap_res_querydomain); |
785 |
+ test_function ("res_send", &wrap_res_send); |
786 |
+ |
787 |
+ test_function ("res_nquery", &wrap_res_nquery); |
788 |
+ test_function ("res_nsearch", &wrap_res_nsearch); |
789 |
+ test_function ("res_nquerydomain", &wrap_res_nquerydomain); |
790 |
+ test_function ("res_nsend", &wrap_res_nsend); |
791 |
+ |
792 |
+ resolv_test_end (obj); |
793 |
+ return 0; |
794 |
+} |
795 |
+ |
796 |
+#define TIMEOUT 300 |
797 |
+#include <support/test-driver.c> |
798 |
-- |
799 |
2.11.0 |