Gentoo Archives: gentoo-commits

From: "Matthias Maier (tamiko)" <tamiko@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo commit in src/patchsets/glibc/2.23: 00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch 00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch 00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch 00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch 00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch README.history
Date: Mon, 19 Jun 2017 16:44:28
Message-Id: 20170619164343.97D747481@oystercatcher.gentoo.org
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