[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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 <string.h>
#include <netdb.h>
#include <signal.h>

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
`. `'   aurel32@debian.org         | aurelien@aurel32.net
  `-    people.debian.org/~aurel32 | www.aurel32.net





Reply to: