getaddrinfo_a stack overflow on 64bit - hardy
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GLibC |
Fix Released
|
Medium
|
|||
glibc (Debian) |
Fix Released
|
Unknown
|
|||
glibc (Ubuntu) |
Fix Released
|
Medium
|
Unassigned |
Bug Description
/home/mcmanus/
Description: Ubuntu 8.04.1
Release: 8.04
/home/mcmanus/
libc6:
Installed: 2.7-10ubuntu3
Candidate: 2.7-10ubuntu3
Version table:
*** 2.7-10ubuntu3 0
500 http://
100 /var/lib/
--
I think this is an upstream bug.
This sample program crashes due to a stack overflow on a thread spawned by glibc. I am not sure if that is also true on 32bit.
(Complile as gcc poc.c -lresolv -ldl -lpthread -lanl )
#define _GNU_SOURCE
#include <netdb.h>
#include <string.h>
main()
{
struct gaicb gb, *list[1];
struct addrinfo hints;
memset (&hints, 0 , sizeof (hints));
list[0] = &gb;
memset (&gb, 0, sizeof (gb));
gb.ar_name = "www.ducksong.com";
gb.ar_service = NULL;
gb.ar_request = &hints;
gb.ar_result = NULL;
getaddrinfo_a (GAI_WAIT, list, 1, NULL);
return 0;
}
In addition to the SEGV, valgrind reports
==21077==
==21077== Process terminating with default action of signal 11 (SIGSEGV)
==21077== Bad permissions for mapped region at address 0x4023A88
==21077== at 0x57477CC: __res_vinit (res_init.c:571)
==21077== by 0x7FF0005FF: ???
==21077== by 0x802BF: ???
The following patch to libc lets the program run without error and gets valgrind a clean bill of health.
diff -ur glibc-2.
--- glibc-2.
+++ ../../glibc-
@@ -97,7 +97,7 @@
pthread_
/* The helper thread needs only very little resources. */
- (void) pthread_
+ (void) pthread_
/* Block all signals in the helper thread. To do this thoroughly we
temporarily have to block all signals here. */
Changed in glibc: | |
importance: | Undecided → Medium |
status: | New → Triaged |
Changed in glibc: | |
status: | Unknown → Confirmed |
Changed in glibc: | |
status: | Unknown → Confirmed |
Changed in glibc: | |
status: | Confirmed → Fix Released |
Changed in glibc: | |
importance: | Unknown → Medium |
Changed in glibc (Debian): | |
status: | Confirmed → Fix Released |
Changed in glibc (Ubuntu): | |
status: | Triaged → Fix Released |
The following code segfaults with at least glibc >= 2.7 (and CVS). It works
correctly with versions 2.3.X. I have tested versions in between.
#define _GNU_SOURCE
#include <string.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
int
main (void)
{
#define N 10
struct gaicb reqmem[N];
struct gaicb *req[N];
int n;
for (n = 0; n < N; ++n) n].ar_name, "test%d. test.redhat. com", 140 + n); n].ar_service = NULL; n].ar_request = NULL; n].ar_result = NULL;
{
asprintf (&reqmem[
reqmem[
reqmem[
reqmem[
req[n] = &reqmem[n];
}
getaddrinfo_a (GAI_NOWAIT, req, N, NULL);
return 0;
}