Bug#495007: libc6: getaddrinfo_a causes SetFault in amd64 version
Package: libc6 Version: 2.7-13 Severity: important Tags: patch getaddrinfo_a creates a segfault in its worker thread due to the stack size being too small. Segfault happens here: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x40003950 (LWP 25753)] __res_vinit (statp=0x40003dc8, preinit=0) at res_init.c:179 179 statp->id = res_randomid(); Upon entering __res_vinit, the stack pointer goes into the 0x1000 byte guard region at the bottom of the thread's segment. The call into res_randomid causes the segment violation. The code in res_randomid is never reached. Here is a sample program to tickle the bug: #include #include #include int main(void) { int ret_val; struct sigevent sig; struct gaicb gaistruct; memset(&gaistruct, 0, sizeof(gaistruct)); struct gaicb *gptr[1]; gptr[0] = &gaistruct; memset(&sig, 0, sizeof(sig)); gptr[0]->ar_name = "a"; sig.sigev_notify = SIGEV_NONE; ret_val = getaddrinfo_a(GAI_WAIT, gptr, 1, &sig); return 0; } Root cause of the bug is in debian/linuxthreads/sysdeps/pthread/ gai_misc.h. The code sets the stack size for the worker thread to the pthreads minimum. This is just not enough. System Information: Debian Release: lenny/sid APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 2.6.22.6091807 (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages libc6 depends on: ii libgcc1 1:4.3.1-2 GCC support library libc6 recommends no packages. Versions of packages libc6 suggests: pn glibc-doc (no description available) ii locales 2.7-13 GNU C Library: National Language ( -- debconf information excluded --- glibc-2.7/resolv/gai_misc.c.orig2008-08-13 14:44:03.0 -0400 +++ glibc-2.7/resolv/gai_misc.c 2008-08-13 14:44:28.0 -0400 @@ -39,7 +39,6 @@ /* Make sure the thread is created detached. */ pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attr, 32768); int ret = pthread_create (threadp, &attr, tf, arg); --- ./glibc-2.7/nptl/sysdeps/pthread/gai_misc.h.orig 2008-08-13 14:46:57.0 -0400 +++ ./glibc-2.7/nptl/sysdeps/pthread/gai_misc.h 2008-08-13 14:47:24.0 -0400 @@ -96,8 +96,8 @@ pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - /* The helper thread needs only very little resources. */ - (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); + /* The helper thread needs only very little resources - but more than PTHREAD_STACK_MIN. */ + (void) pthread_attr_setstacksize (&attr, 32768); /* Block all signals in the helper thread. To do this thoroughly we temporarily have to block all signals here. */ -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Bug#495007: libc6: getaddrinfo_a causes SetFault in amd64 version
Aurelien, I doubt "linuxthreads" is anything but an old directory being reused. The file gai_misc.h appears in two places. The one I mention below in the debian and another in the ./resolve directory. The debian tree version appears to be someone's attempt at optimizing memory usage on the secondary thread. The debian version overrides the libc/resolve version. The secondary thread is created by a conventional pthreads call (again unrelated to "linuxthreads"). The reduced stack size is now being pounded by what appears to be a ton of relatively new getaddrinfo code. __res_vinit() has a large buffer it takes out of the stack. It makes sense that the stack is now to small. I ask that you give the bug serious consideration as written. I followed this through from several angles: register analysis, note of mmap/mprotect commands in strace, gdb si stepping, and finally code changes with unit tests. Thanks, Matthew On Aug 13, 2008, at 7:38 PM, Aurelien Jarno wrote: On Wed, Aug 13, 2008 at 02:53:44PM -0400, Matthew Von-Maszewski wrote: Package: libc6 Version: 2.7-13 Severity: important Tags: patch getaddrinfo_a creates a segfault in its worker thread due to the stack size being too small. Segfault happens here: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x40003950 (LWP 25753)] __res_vinit (statp=0x40003dc8, preinit=0) at res_init.c:179 179 statp->id = res_randomid(); Upon entering __res_vinit, the stack pointer goes into the 0x1000 byte guard region at the bottom of the thread's segment. The call into res_randomid causes the segment violation. The code in res_randomid is never reached. Here is a sample program to tickle the bug: #include #include #include int main(void) { int ret_val; struct sigevent sig; struct gaicb gaistruct; memset(&gaistruct, 0, sizeof(gaistruct)); struct gaicb *gptr[1]; gptr[0] = &gaistruct; memset(&sig, 0, sizeof(sig)); gptr[0]->ar_name = "a"; sig.sigev_notify = SIGEV_NONE; ret_val = getaddrinfo_a(GAI_WAIT, gptr, 1, &sig); return 0; } Root cause of the bug is in debian/linuxthreads/sysdeps/pthread/ gai_misc.h. The code sets the stack size for Are you kidding? linuxthreads is not used on amd64 for a long time. Given this code is not even compiled on amd64, it can't be the root of the problem. -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `-people.debian.org/~aurel32 | www.aurel32.net -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Bug#495007: libc6: getaddrinfo_a causes SetFault in amd64 version
Aurelien, I can truly appreciate your hesitation with this bug report. I can see how stupid this must look from your view point. May I suggest this: - verify whether or not debian/linuxthreads/sysdeps/pthread/gai_misc.h really contributes to a build. Simply put garbage characters in the file and run a build. If our analysis is correct, your build will fail. We saw the file being used. - try the test program contributed by Jon. Try it even if you have a 32 bit box. The size of stack overflow is large enough that I suspect the amd64 is not really a key issue. - we have a highly reproducible case. Ask for any and all supporting data. I can provide it: register snap shots by frame, disassembly step through/to the crash point, etc. I can be a resource. Matthew On Aug 13, 2008, at 9:10 PM, Aurelien Jarno wrote: On Wed, Aug 13, 2008 at 08:23:31PM -0400, Matthew Von-Maszewski wrote: Aurelien, I doubt "linuxthreads" is anything but an old directory being reused. The file gai_misc.h appears in two places. The one I mention below in the debian and another in the ./resolve directory. The debian tree version appears to be someone's attempt at optimizing memory usage on the secondary thread. The debian version overrides the libc/resolve version. The secondary thread is created by a conventional pthreads call (again unrelated to "linuxthreads"). I don't understand why you are speaking about a debian version, debian does not patch this file, so there is nothing about optimizing memory usage. The reduced stack size is now being pounded by what appears to be a ton of relatively new getaddrinfo code. __res_vinit() has a large buffer it takes out of the stack. It makes sense that the stack is now to small. I ask that you give the bug serious consideration as written. I I haven't found yet a time to get a closer look, but your analysis seems to be wrong given that: - we are not using the linuxthreads anymore - we do not change gai_misc.h I'll have a closer look tomorrow. -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `-people.debian.org/~aurel32 | www.aurel32.net -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]