]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/glibc/glibc-rh797094-1.patch
Merge remote-tracking branch 'stevee/mc-update' into thirteen
[people/pmueller/ipfire-2.x.git] / src / patches / glibc / glibc-rh797094-1.patch
CommitLineData
12788f63
MT
1diff -rup a/include/alloca.h b/include/alloca.h
2--- a/include/alloca.h 2012-02-29 13:11:19.439693476 -0700
3+++ b/include/alloca.h 2012-02-29 13:11:49.832530623 -0700
4@@ -49,15 +49,24 @@ libc_hidden_proto (__libc_alloca_cutoff)
5
6 #if defined stackinfo_get_sp && defined stackinfo_sub_sp
7 # define alloca_account(size, avar) \
8- ({ void *old__ = stackinfo_get_sp (); \
9- void *m__ = __alloca (size); \
10- avar += stackinfo_sub_sp (old__); \
11+ ({ void *old__ = stackinfo_get_sp (); \
12+ void *m__ = __alloca (size); \
13+ avar += stackinfo_sub_sp (old__); \
14+ m__; })
15+# define extend_alloca_account(buf, len, newlen, avar) \
16+ ({ void *old__ = stackinfo_get_sp (); \
17+ void *m__ = extend_alloca (buf, len, newlen); \
18+ avar += stackinfo_sub_sp (old__); \
19 m__; })
20 #else
21 # define alloca_account(size, avar) \
22- ({ size_t s__ = (size); \
23- avar += s__; \
24+ ({ size_t s__ = (size); \
25+ avar += s__; \
26 __alloca (s__); })
27+# define extend_alloca_account(buf, len, newlen, avar) \
28+ ({ size_t s__ = (newlen); \
29+ avar += s__; \
30+ extend_alloca (buf, len, s__); })
31 #endif
32
33 #endif
34diff -rup a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
35--- a/sysdeps/posix/getaddrinfo.c 2012-02-29 13:11:19.588692676 -0700
36+++ b/sysdeps/posix/getaddrinfo.c 2012-02-29 13:12:42.972245862 -0700
37@@ -278,6 +278,7 @@ gaih_inet (const char *name, const struc
38 bool got_ipv6 = false;
39 const char *canon = NULL;
40 const char *orig_name = name;
41+ size_t alloca_used = 0;
42
43 if (req->ai_protocol || req->ai_socktype)
44 {
45@@ -310,7 +311,7 @@ gaih_inet (const char *name, const struc
46 if (tp->name[0])
47 {
48 st = (struct gaih_servtuple *)
49- __alloca (sizeof (struct gaih_servtuple));
50+ alloca_account (sizeof (struct gaih_servtuple), alloca_used);
51
52 if ((rc = gaih_inet_serv (service->name, tp, req, st)))
53 return rc;
54@@ -334,7 +335,8 @@ gaih_inet (const char *name, const struc
55 continue;
56
57 newp = (struct gaih_servtuple *)
58- __alloca (sizeof (struct gaih_servtuple));
59+ alloca_account (sizeof (struct gaih_servtuple),
60+ alloca_used);
61
62 if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
63 {
64@@ -362,7 +364,7 @@ gaih_inet (const char *name, const struc
65
66 if (req->ai_socktype || req->ai_protocol)
67 {
68- st = __alloca (sizeof (struct gaih_servtuple));
69+ st = alloca_account (sizeof (struct gaih_servtuple), alloca_used);
70 st->next = NULL;
71 st->socktype = tp->socktype;
72 st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
73@@ -379,7 +381,8 @@ gaih_inet (const char *name, const struc
74 {
75 struct gaih_servtuple *newp;
76
77- newp = __alloca (sizeof (struct gaih_servtuple));
78+ newp = alloca_account (sizeof (struct gaih_servtuple),
79+ alloca_used);
80 newp->next = NULL;
81 newp->socktype = tp->socktype;
82 newp->protocol = tp->protocol;
83@@ -391,10 +394,17 @@ gaih_inet (const char *name, const struc
84 }
85 }
86
87+ bool malloc_name = false;
88+ bool malloc_addrmem = false;
89+ struct gaih_addrtuple *addrmem = NULL;
90+ bool malloc_canonbuf = false;
91+ char *canonbuf = NULL;
92+ bool malloc_tmpbuf = false;
93+ char *tmpbuf = NULL;
94+ int result = 0;
95 if (name != NULL)
96 {
97- at = __alloca (sizeof (struct gaih_addrtuple));
98-
99+ at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
100 at->family = AF_UNSPEC;
101 at->scopeid = 0;
102 at->next = NULL;
103@@ -412,6 +422,7 @@ gaih_inet (const char *name, const struc
104 rc = __idna_to_ascii_lz (name, &p, idn_flags);
105 if (rc != IDNA_SUCCESS)
106 {
107+ /* No need to jump to free_and_return here. */
108 if (rc == IDNA_MALLOC_ERROR)
109 return -EAI_MEMORY;
110 if (rc == IDNA_DLOPEN_ERROR)
111@@ -421,10 +432,7 @@ gaih_inet (const char *name, const struc
112 /* In case the output string is the same as the input string
113 no new string has been allocated. */
114 if (p != name)
115- {
116- name = strdupa (p);
117- free (p);
118- }
119+ malloc_name = true;
120 }
121 #endif
122
123@@ -441,23 +449,59 @@ gaih_inet (const char *name, const struc
124 at->family = AF_INET6;
125 }
126 else
127- return -EAI_ADDRFAMILY;
128+ {
129+ result = -EAI_ADDRFAMILY;
130+ goto free_and_return;
131+ }
132
133 if (req->ai_flags & AI_CANONNAME)
134 canon = name;
135 }
136 else if (at->family == AF_UNSPEC)
137 {
138- char *namebuf = (char *) name;
139 char *scope_delim = strchr (name, SCOPE_DELIMITER);
140+ int e;
141
142- if (__builtin_expect (scope_delim != NULL, 0))
143- {
144- namebuf = alloca (scope_delim - name + 1);
145- *((char *) __mempcpy (namebuf, name, scope_delim - name)) = '\0';
146- }
147+ {
148+ bool malloc_namebuf = false;
149+ char *namebuf = (char *) name;
150+
151+ if (__builtin_expect (scope_delim != NULL, 0))
152+ {
153+ if (malloc_name)
154+ *scope_delim = '\0';
155+ else
156+ {
157+ if (__libc_use_alloca (alloca_used
158+ + scope_delim - name + 1))
159+ {
160+ namebuf = alloca_account (scope_delim - name + 1,
161+ alloca_used);
162+ *((char *) __mempcpy (namebuf, name,
163+ scope_delim - name)) = '\0';
164+ }
165+ else
166+ {
167+ namebuf = strndup (name, scope_delim - name);
168+ if (namebuf == NULL)
169+ {
170+ assert (!malloc_name);
171+ return -EAI_MEMORY;
172+ }
173+ malloc_namebuf = true;
174+ }
175+ }
176+ }
177
178- if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
179+ e = inet_pton (AF_INET6, namebuf, at->addr);
180+
181+ if (malloc_namebuf)
182+ free (namebuf);
183+ else if (scope_delim != NULL && malloc_name)
184+ /* Undo what we did above. */
185+ *scope_delim = SCOPE_DELIMITER;
186+ }
187+ if (e > 0)
188 {
189 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
190 at->family = AF_INET6;
191@@ -468,7 +512,10 @@ gaih_inet (const char *name, const struc
192 at->family = AF_INET;
193 }
194 else
195- return -EAI_ADDRFAMILY;
196+ {
197+ result = -EAI_ADDRFAMILY;
198+ goto free_and_return;
199+ }
200
201 if (scope_delim != NULL)
202 {
203@@ -490,7 +537,10 @@ gaih_inet (const char *name, const struc
204 at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
205 10);
206 if (*end != '\0')
207- return GAIH_OKIFUNSPEC | -EAI_NONAME;
208+ {
209+ result = GAIH_OKIFUNSPEC | -EAI_NONAME;
210+ goto free_and_return;
211+ }
212 }
213 }
214
215@@ -520,59 +570,80 @@ gaih_inet (const char *name, const struc
216 {
217 int family = req->ai_family;
218 size_t tmpbuflen = 512;
219- char *tmpbuf = alloca (tmpbuflen);
220+ assert (tmpbuf == NULL);
221+ tmpbuf = alloca_account (tmpbuflen, alloca_used);
222 int rc;
223 struct hostent th;
224 struct hostent *h;
225 int herrno;
226
227- simple_again:
228 while (1)
229 {
230- rc = __gethostbyname2_r (name, family, &th, tmpbuf,
231+ rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf,
232 tmpbuflen, &h, &herrno);
233 if (rc != ERANGE || herrno != NETDB_INTERNAL)
234 break;
235- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen);
236+
237+ if (!malloc_tmpbuf
238+ && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
239+ tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
240+ 2 * tmpbuflen,
241+ alloca_used);
242+ else
243+ {
244+ char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
245+ 2 * tmpbuflen);
246+ if (newp == NULL)
247+ {
248+ result = -EAI_MEMORY;
249+ goto free_and_return;
250+ }
251+ tmpbuf = newp;
252+ malloc_tmpbuf = true;
253+ tmpbuflen = 2 * tmpbuflen;
254+ }
255 }
256
257 if (rc == 0)
258 {
259- if (h == NULL)
260+ if (h != NULL)
261 {
262- if (req->ai_family == AF_INET6
263- && (req->ai_flags & AI_V4MAPPED)
264- && family == AF_INET6)
265+ int i;
266+ /* We found data, count the number of addresses. */
267+ for (i = 0; h->h_addr_list[i]; ++i)
268+ ;
269+ if (i > 0 && *pat != NULL)
270+ --i;
271+
272+ if (__libc_use_alloca (alloca_used
273+ + i * sizeof (struct gaih_addrtuple)))
274+ addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
275+ alloca_used);
276+ else
277 {
278- /* Try again, this time looking for IPv4
279- addresses. */
280- family = AF_INET;
281- goto simple_again;
282+ addrmem = malloc (i
283+ * sizeof (struct gaih_addrtuple));
284+ if (addrmem == NULL)
285+ {
286+ result = -EAI_MEMORY;
287+ goto free_and_return;
288 }
289+ malloc_addrmem = true;
290 }
291- else
292- {
293- /* We found data, now convert it into the list. */
294- for (int i = 0; h->h_addr_list[i]; ++i)
295+
296+ /* Now convert it into the list. */
297+ struct gaih_addrtuple *addrfree = addrmem;
298+ for (i = 0; h->h_addr_list[i]; ++i)
299 {
300 if (*pat == NULL)
301 {
302- *pat = __alloca (sizeof (struct gaih_addrtuple));
303+ *pat = addrfree++;
304 (*pat)->scopeid = 0;
305 }
306 (*pat)->next = NULL;
307- (*pat)->family = req->ai_family;
308- if (family == req->ai_family)
309+ (*pat)->family = AF_INET;
310 memcpy ((*pat)->addr, h->h_addr_list[i],
311 h->h_length);
312- else
313- {
314- uint32_t *addr = (uint32_t *) (*pat)->addr;
315- addr[3] = *(uint32_t *) h->h_addr_list[i];
316- addr[2] = htonl (0xffff);
317- addr[1] = 0;
318- addr[0] = 0;
319- }
320 pat = &((*pat)->next);
321 }
322 }
323@@ -582,15 +653,16 @@ gaih_inet (const char *name, const struc
324 if (herrno == NETDB_INTERNAL)
325 {
326 __set_h_errno (herrno);
327- return -EAI_SYSTEM;
328- }
329- if (herrno == TRY_AGAIN)
330- {
331- return -EAI_AGAIN;
332+ result = -EAI_SYSTEM;
333 }
334+ else if (herrno == TRY_AGAIN)
335+ result = -EAI_AGAIN;
336+ else
337 /* We made requests but they turned out no data.
338 The name is known, though. */
339- return GAIH_OKIFUNSPEC | -EAI_NODATA;
340+ result = GAIH_OKIFUNSPEC | -EAI_NODATA;
341+
342+ goto free_and_return;
343 }
344
345 goto process_list;
346@@ -613,21 +685,56 @@ gaih_inet (const char *name, const struc
347 bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
348 char *addrs = air->addrs;
349
350+ if (__libc_use_alloca (alloca_used
351+ + air->naddrs * sizeof (struct gaih_addrtuple)))
352+ addrmem = alloca_account (air->naddrs
353+ * sizeof (struct gaih_addrtuple),
354+ alloca_used);
355+ else
356+ {
357+ addrmem = malloc (air->naddrs
358+ * sizeof (struct gaih_addrtuple));
359+ if (addrmem == NULL)
360+ {
361+ result = -EAI_MEMORY;
362+ goto free_and_return;
363+ }
364+ malloc_addrmem = true;
365+ }
366+
367+ struct gaih_addrtuple *addrfree = addrmem;
368 for (int i = 0; i < air->naddrs; ++i)
369 {
370 socklen_t size = (air->family[i] == AF_INET
371 ? INADDRSZ : IN6ADDRSZ);
372 if (*pat == NULL)
373 {
374- *pat = __alloca (sizeof (struct gaih_addrtuple));
375+ *pat = addrfree++;
376 (*pat)->scopeid = 0;
377 }
378 uint32_t *pataddr = (*pat)->addr;
379 (*pat)->next = NULL;
380 if (added_canon || air->canon == NULL)
381 (*pat)->name = NULL;
382- else
383- canon = (*pat)->name = strdupa (air->canon);
384+ else if (canonbuf == NULL)
385+ {
386+ size_t canonlen = strlen (air->canon) + 1;
387+ if ((req->ai_flags & AI_CANONIDN) != 0
388+ && __libc_use_alloca (alloca_used + canonlen))
389+ canonbuf = alloca_account (canonlen, alloca_used);
390+ else
391+ {
392+ canonbuf = malloc (canonlen);
393+ if (canonbuf == NULL)
394+ {
395+ result = -EAI_MEMORY;
396+ goto free_and_return;
397+ }
398+ malloc_canonbuf = true;
399+ }
400+ canon = (*pat)->name = memcpy (canonbuf, air->canon,
401+ canonlen);
402+ }
403
404 if (air->family[i] == AF_INET
405 && req->ai_family == AF_INET6
406@@ -657,20 +764,26 @@ gaih_inet (const char *name, const struc
407 free (air);
408
409 if (at->family == AF_UNSPEC)
410- return GAIH_OKIFUNSPEC | -EAI_NONAME;
411+ {
412+ result = GAIH_OKIFUNSPEC | -EAI_NONAME;
413+ goto free_and_return;
414+ }
415
416 goto process_list;
417 }
418 else if (err == 0)
419 /* The database contains a negative entry. */
420- return 0;
421+ goto free_and_return;
422 else if (__nss_not_use_nscd_hosts == 0)
423 {
424 if (herrno == NETDB_INTERNAL && errno == ENOMEM)
425- return -EAI_MEMORY;
426- if (herrno == TRY_AGAIN)
427- return -EAI_AGAIN;
428- return -EAI_SYSTEM;
429+ result = -EAI_MEMORY;
430+ else if (herrno == TRY_AGAIN)
431+ result = -EAI_AGAIN;
432+ else
433+ result = -EAI_SYSTEM;
434+
435+ goto free_and_return;
436 }
437 }
438 #endif
439@@ -699,7 +812,19 @@ gaih_inet (const char *name, const struc
440 _res.options &= ~RES_USE_INET6;
441
442 size_t tmpbuflen = 1024;
443- char *tmpbuf = alloca (tmpbuflen);
444+ malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
445+ assert (tmpbuf == NULL);
446+ if (!malloc_tmpbuf)
447+ tmpbuf = alloca_account (tmpbuflen, alloca_used);
448+ else
449+ {
450+ tmpbuf = malloc (tmpbuflen);
451+ if (tmpbuf == NULL)
452+ {
453+ result = -EAI_MEMORY;
454+ goto free_and_return;
455+ }
456+ }
457
458 while (!no_more)
459 {
460@@ -728,8 +853,25 @@ gaih_inet (const char *name, const struc
461 no_data = herrno == NO_DATA;
462 break;
463 }
464- tmpbuf = extend_alloca (tmpbuf,
465- tmpbuflen, 2 * tmpbuflen);
466+
467+ if (!malloc_tmpbuf
468+ && __libc_use_alloca (alloca_used + 2 * tmpbuflen))
469+ tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
470+ 2 * tmpbuflen,
471+ alloca_used);
472+ else
473+ {
474+ char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
475+ 2 * tmpbuflen);
476+ if (newp == NULL)
477+ {
478+ result = -EAI_MEMORY;
479+ goto free_and_return;
480+ }
481+ tmpbuf = newp;
482+ malloc_tmpbuf = true;
483+ tmpbuflen = 2 * tmpbuflen;
484+ }
485 }
486
487 if (status == NSS_STATUS_SUCCESS)
488@@ -832,18 +974,40 @@ gaih_inet (const char *name, const struc
489 if (cfct != NULL)
490 {
491 const size_t max_fqdn_len = 256;
492- char *buf = alloca (max_fqdn_len);
493+ if ((req->ai_flags & AI_CANONIDN) != 0
494+ && __libc_use_alloca (alloca_used
495+ + max_fqdn_len))
496+ canonbuf = alloca_account (max_fqdn_len,
497+ alloca_used);
498+ else
499+ {
500+ canonbuf = malloc (max_fqdn_len);
501+ if (canonbuf == NULL)
502+ {
503+ result = -EAI_MEMORY;
504+ goto free_and_return;
505+ }
506+ malloc_canonbuf = true;
507+ }
508 char *s;
509
510 if (DL_CALL_FCT (cfct, (at->name ?: name,
511- buf, max_fqdn_len,
512+ canonbuf,
513+ max_fqdn_len,
514 &s, &rc, &herrno))
515 == NSS_STATUS_SUCCESS)
516 canon = s;
517 else
518- /* Set to name now to avoid using
519- gethostbyaddr. */
520- canon = name;
521+ {
522+ /* Set to name now to avoid using
523+ gethostbyaddr. */
524+ if (malloc_canonbuf)
525+ {
526+ free (canonbuf);
527+ malloc_canonbuf = false;
528+ }
529+ canon = name;
530+ }
531 }
532 }
533 status = NSS_STATUS_SUCCESS;
534@@ -878,22 +1042,27 @@ gaih_inet (const char *name, const struc
535 {
536 /* If both requests timed out report this. */
537 if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
538- return -EAI_AGAIN;
539+ result = -EAI_AGAIN;
540+ else
541+ /* We made requests but they turned out no data. The name
542+ is known, though. */
543+ result = GAIH_OKIFUNSPEC | -EAI_NODATA;
544
545- /* We made requests but they turned out no data. The name
546- is known, though. */
547- return GAIH_OKIFUNSPEC | -EAI_NODATA;
548+ goto free_and_return;
549 }
550 }
551
552 process_list:
553 if (at->family == AF_UNSPEC)
554- return GAIH_OKIFUNSPEC | -EAI_NONAME;
555+ {
556+ result = GAIH_OKIFUNSPEC | -EAI_NONAME;
557+ goto free_and_return;
558+ }
559 }
560 else
561 {
562 struct gaih_addrtuple *atr;
563- atr = at = __alloca (sizeof (struct gaih_addrtuple));
564+ atr = at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
565 memset (at, '\0', sizeof (struct gaih_addrtuple));
566
567 if (req->ai_family == AF_UNSPEC)
568@@ -932,6 +1101,9 @@ gaih_inet (const char *name, const struc
569 /* Only the first entry gets the canonical name. */
570 if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
571 {
572+ char *tmpbuf2 = NULL;
573+ bool malloc_tmpbuf2 = false;
574+
575 if (canon == NULL)
576 {
577 /* If the canonical name cannot be determined, use
578@@ -952,11 +1124,16 @@ gaih_inet (const char *name, const struc
579 int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
580 if (rc != IDNA_SUCCESS)
581 {
582+ if (malloc_tmpbuf2)
583+ free (tmpbuf2);
584+
585 if (rc == IDNA_MALLOC_ERROR)
586- return -EAI_MEMORY;
587- if (rc == IDNA_DLOPEN_ERROR)
588- return -EAI_SYSTEM;
589- return -EAI_IDN_ENCODE;
590+ result = -EAI_MEMORY;
591+ else if (rc == IDNA_DLOPEN_ERROR)
592+ result = -EAI_SYSTEM;
593+ else
594+ result = -EAI_IDN_ENCODE;
595+ goto free_and_return;
596 }
597 /* In case the output string is the same as the input
598 string no new string has been allocated and we
599@@ -970,10 +1147,25 @@ gaih_inet (const char *name, const struc
600 #ifdef HAVE_LIBIDN
601 make_copy:
602 #endif
603- canon = strdup (canon);
604- if (canon == NULL)
605- return -EAI_MEMORY;
606+ if (malloc_canonbuf)
607+ /* We already allocated the string using malloc. */
608+ malloc_canonbuf = false;
609+ else
610+ {
611+ canon = strdup (canon);
612+ if (canon == NULL)
613+ {
614+ if (malloc_tmpbuf2)
615+ free (tmpbuf2);
616+
617+ result = -EAI_MEMORY;
618+ goto free_and_return;
619+ }
620+ }
621 }
622+
623+ if (malloc_tmpbuf2)
624+ free (tmpbuf2);
625 }
626
627 family = at2->family;
628@@ -999,7 +1191,8 @@ gaih_inet (const char *name, const struc
629 if (ai == NULL)
630 {
631 free ((char *) canon);
632- return -EAI_MEMORY;
633+ result = -EAI_MEMORY;
634+ goto free_and_return;
635 }
636
637 ai->ai_flags = req->ai_flags;
638@@ -1052,7 +1245,18 @@ gaih_inet (const char *name, const struc
639 at2 = at2->next;
640 }
641 }
642- return 0;
643+
644+ free_and_return:
645+ if (malloc_name)
646+ free ((char *) name);
647+ if (malloc_addrmem)
648+ free (addrmem);
649+ if (malloc_canonbuf)
650+ free (canonbuf);
651+ if (malloc_tmpbuf)
652+ free (tmpbuf);
653+
654+ return result;
655 }
656
657