Bug#228375: hppa glibc, elf_machine_runtime_setup() segv, with patch
package: glibc
version: 2.3.2.ds1-10
tags: d-i
This relates to running debian-installer on hppa/parisc.
When d-i runs frontend, it results in SEGV:
~ # LD_DEBUG=reloc DEBIAN_FRONTEND=newt /usr/share/debconf/frontend /usr/bin/main-menu
13764:
13764: relocation processing: /lib/libc.so.6 (lazy)
13764:
13764: relocation processing: /lib/libtextwrap.so.1 (lazy)
13764:
13764: relocation processing: /lib/libdl.so.2 (lazy)
13764:
13764: relocation processing: /usr/lib/cdebconf/libdebconf.so (lazy)
13764:
13764: relocation processing: /usr/share/debconf/frontend (lazy)
13764:
13764: relocation processing: /lib/ld.so.1
13764:
13764: calling init: /lib/libc.so.6
13764:
13764:
13764: calling init: /lib/libtextwrap.so.1
13764:
13764:
13764: calling init: /lib/libdl.so.2
13764:
13764:
13764: calling init: /usr/lib/cdebconf/libdebconf.so
13764:
13764:
13764: initialize program: /usr/share/debconf/frontend
13764:
13764:
13764: transferring control: /usr/share/debconf/frontend
13764:
13764:
13764: relocation processing: /usr/lib/cdebconf/db/rfc822db.so
13764:
13764: calling init: /usr/lib/cdebconf/db/rfc822db.so
13764:
13764:
13764: relocation processing: /lib/libslang.so.1-UTF8 (lazy)
13764:
13764: relocation processing: /lib/libm.so.6 (lazy)
Segmentation fault
~ #
The build process for debian-installer uses mklibs to reduce library sizes. In
that process, it ends up reducing libm to nothing:
richard@slab:/build/ptrace$ readelf -S /build/debian-installer/debian-installer-head/build/tmp/netboot/tree/lib/libm.so.6
There are 12 section headers, starting at offset 0x2f4:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .hash HASH 00000094 000094 000044 04 A 2 0 4
[ 2] .dynsym DYNSYM 000000d8 0000d8 0000c0 10 A 3 b 4
[ 3] .dynstr STRTAB 00000198 000198 00001f 00 A 0 0 1
[ 4] .gnu.version VERSYM 000001b8 0001b8 000018 02 A 2 0 2
[ 5] .gnu.version_d VERDEF 000001d0 0001d0 000038 00 A 3 2 4
[ 6] .data PROGBITS 00010208 000298 000000 00 W 0 0 1
[ 7] .dynamic DYNAMIC 00010208 000208 000088 08 WA 3 0 4
[ 8] .got PROGBITS 00010290 000290 000008 04 WA 0 0 4
[ 9] .sbss PROGBITS 00010298 000298 000000 00 W 0 0 1
[10] .bss NOBITS 00010298 000298 000000 00 WA 0 0 1
[11] .shstrtab STRTAB 00000000 000298 00005c 00 0 0 1
and there is no DT_JMPREL entry in the dynamic section:
richard@slab:/build/ptrace$ objdump -p /build/debian-installer/debian-installer-head/build/tmp/netboot/tree/lib/libm.so.6
/build/debian-installer/debian-installer-head/build/tmp/netboot/tree/lib/libm.so.6: file format elf32-hppa-linux
Program Header:
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
filesz 0x00000208 memsz 0x00000208 flags r--
LOAD off 0x00000208 vaddr 0x00010208 paddr 0x00010208 align 2**12
filesz 0x00000090 memsz 0x00000090 flags rw-
DYNAMIC off 0x00000208 vaddr 0x00010208 paddr 0x00010208 align 2**2
filesz 0x00000088 memsz 0x00000088 flags rw-
Dynamic Section:
NEEDED libc.so.6
SONAME libm.so.6
HASH 0x94
STRTAB 0x198
SYMTAB 0xd8
STRSZ 0x1f
SYMENT 0x10
PLTGOT 0x0
VERDEF 0x1d0
VERDEFNUM 0x2
VERSYM 0x1b8
Version definitions:
1 0x01 0x0905f4e6 libm.so.6
2 0x00 0x0d696912 GLIBC_2.2
As a result, it dies in elf_machine_runtime_setup(), called from
_dl_relocate_object(), for libm.
elf_machine_runtime_setup() has:
Elf32_Addr jmprel = D_PTR(l, l_info[DT_JMPREL]);
and as
# define D_PTR(map,i) map->i->d_un.d_ptr
that is effectively:
jmprel = l->l_info[DT_JMPREL]->d_un.d_ptr
and as there is no JMPREL entry in the dynamic section, that results in a
null pointer dref.
I looked at the equivalent i386 code, and that tests l->l_info[DT_JMPREL]
before trying to use it.
I guess something like this might fix the hppa code, but I havn't tested
it:
--- glibc-2.3.2/sysdeps/hppa/dl-machine.h- 2004-01-18 16:22:44.000000000 +0000
+++ glibc-2.3.2/sysdeps/hppa/dl-machine.h 2004-01-18 16:24:00.000000000 +0000
@@ -143,10 +143,10 @@
{
extern void _dl_runtime_resolve (void);
extern void _dl_runtime_profile (void);
- Elf32_Addr jmprel = D_PTR(l, l_info[DT_JMPREL]);
- if (lazy && jmprel)
+ if (l->l_info[DT_JMPREL] && lazy)
{
+ Elf32_Addr jmprel = D_PTR(l, l_info[DT_JMPREL]);
Elf32_Addr *got = NULL;
Elf32_Addr l_addr;
Elf32_Addr end_jmprel;
Thanks,
Richard
Reply to: