Re: bin-x86_64/diet segfaults in findtlsdata()
[email protected] Mon, 6 Aug 2018 14:28:48 +0200 (CEST)
| Newsgroups | gmane.linux.lib.dietlibc |
|---|---|
| Message-ID | <[email protected]> |
> On August 6, 2018 at 1:54 PM [email protected] wrote: > > > Hi, > > I'm getting a new segfault while building the current dietlibc cvs: > > ... > make: Entering directory '/tmp/dietlibc-cvs' > bin-x86_64/diet gcc -D__dietlibc__ -g -O0 -march=native -Wall -fno-stack-protector -std=gnu99 -W -Wall -Wextra -Wchar-subscripts -Wmissing-prototypes -Wmissing-declarations -Wno-switch -Wno-unused -Wredundant-decls -Wshadow -o bin-x86_64/elftrunc contrib/elftrunc.c > make: *** [Makefile:346: bin-x86_64/elftrunc] Segmentation fault > > > After a bit of gdbugging here is the segfault context: > > inside the function findtlsdata(long* auxvec) in lib/stackgap-common.h: > > ... > static void findtlsdata(long* auxvec) { > #if (__WORDSIZE == 64) > Elf64_Phdr* x=0; > #else > Elf32_Phdr* x=0; > #endif > size_t i,n=0; > while (*auxvec) { > if (auxvec[0]==3) { /* AT_PHDR */ > x=(void*)auxvec[1]; > if (n) break; > } else if (auxvec[0]==5) { /* AT_PHNUM */ > n=auxvec[1]; > if (x) break; > } > auxvec+=2; > } /* if we don't find the entry, the kernel let us down */ > if (!x || !n) return; /* a kernel this old does not support thread local storage anyway */ > for (i=0; i<n; ++i) > if (x[i].p_type==PT_TLS) { > __tdataptr=(void*)x[i].p_vaddr; > __tdatasize=x[i].p_filesz; > __tmemsize=x[i].p_memsz; > if (__tmemsize&15) > __tmemsize=(__tmemsize+15)&~15; > break; > } > /* if there is no PT_TLS section, there is no thread-local data, and > * we just leave the __t* variables zero */ > } > ... > > it searches the auxvec table for the PHDR address and the PHNUM and it actually finds something: > here is a memory dump of the auxvec in gdb: > > (gdb) x/40ug auxvec > 0x7fffffffe1e8: 33 140737354125312 > 0x7fffffffe1f8: 16 3219913727 > 0x7fffffffe208: 6 4096 > 0x7fffffffe218: 17 100 > 0x7fffffffe228: 3 4194368 > 0x7fffffffe238: 4 56 > 0x7fffffffe248: 5 6 > 0x7fffffffe258: 7 0 > 0x7fffffffe268: 8 0 > 0x7fffffffe278: 9 4198400 > 0x7fffffffe288: 11 1000 > 0x7fffffffe298: 12 1000 > 0x7fffffffe2a8: 13 999 > 0x7fffffffe2b8: 14 999 > 0x7fffffffe2c8: 23 0 > 0x7fffffffe2d8: 25 140737488347945 > 0x7fffffffe2e8: 26 0 > 0x7fffffffe2f8: 31 140737488351118 > 0x7fffffffe308: 15 140737488347961 > 0x7fffffffe318: 0 0 > (gdb) x/40xg auxvec > 0x7fffffffe1e8: 0x0000000000000021 0x00007ffff7ffd000 > 0x7fffffffe1f8: 0x0000000000000010 0x00000000bfebfbff > 0x7fffffffe208: 0x0000000000000006 0x0000000000001000 > 0x7fffffffe218: 0x0000000000000011 0x0000000000000064 > 0x7fffffffe228: 0x0000000000000003 0x0000000000400040 > 0x7fffffffe238: 0x0000000000000004 0x0000000000000038 > 0x7fffffffe248: 0x0000000000000005 0x0000000000000006 > 0x7fffffffe258: 0x0000000000000007 0x0000000000000000 > 0x7fffffffe268: 0x0000000000000008 0x0000000000000000 > 0x7fffffffe278: 0x0000000000000009 0x0000000000401000 > 0x7fffffffe288: 0x000000000000000b 0x00000000000003e8 > 0x7fffffffe298: 0x000000000000000c 0x00000000000003e8 > 0x7fffffffe2a8: 0x000000000000000d 0x00000000000003e7 > 0x7fffffffe2b8: 0x000000000000000e 0x00000000000003e7 > 0x7fffffffe2c8: 0x0000000000000017 0x0000000000000000 > 0x7fffffffe2d8: 0x0000000000000019 0x00007fffffffe329 > 0x7fffffffe2e8: 0x000000000000001a 0x0000000000000000 > 0x7fffffffe2f8: 0x000000000000001f 0x00007fffffffef8e > 0x7fffffffe308: 0x000000000000000f 0x00007fffffffe339 > 0x7fffffffe318: 0x0000000000000000 0x0000000000000000 > (gdb) > > The pointer 'x' gets the value 0x400040 and the program segfaults as soon as 'x' > is dereferenced in: > > if (x[i].p_type==PT_TLS) { > > with i==0. > > Can someone recognize something stange in this ? Is the address 0x400040 'plausible' > or is it obviously wrong. > > I'm compiling natively with gcc 8.2 on linux 4.17.11. > > giorgio I suspect this is a bug in recent versions of binutils (2.30 ~ 2.31), see: https://sourceware.org/bugzilla/show_bug.cgi?id=23428 and http://www.openwall.com/lists/musl/2018/07/18/5 giorgio