Note: This bug is displayed in read-only format because
the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
User has /lib64/libdl-2.17.so in /etc/ld.so.preload
They also have a subsystem that executes /lib64/libc.so and parse its output.
The problem happens with new glibc:
$ gdb /lib64/libc-2.17.so
...
(gdb) set environment LD_PRELOAD=/lib64/libdl-2.17.so
(gdb) run
Starting program: /lib64/libc-2.17.so
Program received signal SIGSEGV, Segmentation fault.
strcpy () at ../sysdeps/x86_64/multiarch/strcpy.S:66
66 HAS_ARCH_FEATURE (Fast_Unaligned_Load)
(gdb) bt
#0 strcpy () at ../sysdeps/x86_64/multiarch/strcpy.S:66
#1 0x00007ffff7de76b8 in elf_machine_rela (reloc=0x7ffff7bd7bf8,
reloc=0x7ffff7bd7bf8, skip_ifunc=<optimized out>,
reloc_addr_arg=0x7ffff7dda038, version=<optimized out>,
sym=0x7ffff7bd7368, map=0x7ffff7ff9658)
at ../sysdeps/x86_64/dl-machine.h:308
#2 elf_dynamic_do_Rela (skip_ifunc=<optimized out>, lazy=<optimized out>,
nrelative=<optimized out>, relsize=<optimized out>,
reladdr=<optimized out>, map=0x7ffff7ff9658) at do-rel.h:137
#3 _dl_relocate_object (scope=<optimized out>, reloc_mode=<optimized out>,
consider_profiling=<optimized out>, consider_profiling@entry=0)
at dl-reloc.c:259
#4 0x00007ffff7ddf98a in dl_main (phdr=<optimized out>,
phdr@entry=0x555555554040, phnum=<optimized out>, phnum@entry=10,
user_entry=user_entry@entry=0x7fffffffde18, auxv=<optimized out>)
at rtld.c:2179
Checking disassemble, it attempted to get _dl_x86_cpu_features address
and check a bit on it. But it was a NULL pointer.
(gdb) disassemble
Dump of assembler code for function strcpy:
0x00005555555e07c0 <+0>: mov 0x33a681(%rip),%rdx # 0x55555591ae48
0x00005555555e07c7 <+7>: lea 0xdf12(%rip),%rax # 0x5555555ee6e0 <__strcpy_sse2_unaligned>
=> 0x00005555555e07ce <+14>: testl $0x10,0xb8(%rdx)
(gdb) p *(void**) 0x55555591ae48
$1 = (void *) 0x0
From my understanding, it should have been the same as:
(gdb) p _rtld_local_ro._dl_x86_cpu_features
$2 = {kind = arch_kind_intel, max_cpuid = 13, cpuid = {{eax = 132769,
ebx = 2048, ecx = 2679644675, edx = 126614527}, {eax = 0, ebx = 0,
ecx = 0, edx = 0}, {eax = 0, ebx = 0, ecx = 0, edx = 0}}, family = 6,
model = 42, xsave_state_size = 896, feature = {123}}
(gdb) p& _rtld_local_ro._dl_x86_cpu_features
$3 = (struct cpu_features *) 0x7ffff7ffcc70 <_rtld_local_ro+112>
It should be required some code change to allow preloading libdl.so and
'executing' libc.so; executing a binary works, and it should be related to
sysdeps/x86/libc-start.c:
...
extern struct cpu_features _dl_x86_cpu_features;
int
__libc_start_main (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
int argc, char **argv,
__typeof (main) init,
void (*fini) (void),
void (*rtld_fini) (void), void *stack_end)
{
init_cpu_features (&_dl_x86_cpu_features);
return generic_start_main (main, argc, argv, init, fini, rtld_fini,
stack_end);
}
...
Comment 2Siddhesh Poyarekar
2020-10-15 13:36:09 UTC
Can you provide some information on how this could be fixed temporarily? Or at least
provide some extra information to the customer?
For example, if from gdb I disassemble:
Dump of assembler code for function strcpy:
0x00005555555e07c0 <+0>: mov 0x33a681(%rip),%rdx # 0x55555591ae48
0x00005555555e07c7 <+7>: lea 0xdf12(%rip),%rax # 0x5555555ee6e0 <__strcpy_sse2_unaligned>
=> 0x00005555555e07ce <+14>: testl $0x10,0xb8(%rdx)
and set 0x55555591ae48 to the address of _rtld_local_ro._dl_x86_cpu_features
it will work, at least for the special condition of
"LD_PRELOAD=any_dso /lib64/libc-2.17.so".
(In reply to Paulo Andrade from comment #3)
> Can you provide some information on how this could be fixed temporarily?
(a) Remove libdl from ld.so.preload.
The temporary fix is to remove libdl from the preload list. It cannot be preloaded *and* run libc.so.6 as a binary.
(b) Don't run libc.so.6 and get the information you need from other sources.
Use readelf.
> Or at least provide some extra information to the customer?
When libc.so.6 is run as the binary it is forced into a delayed position in the initialization order during ELF startup.
The preloaded object is loaded first, ahead of libc.so.6, and so is basically unable to rely on any libc.so.6 functionality.
The use of libc.so.6 as a binary is intended to be informative only, and doesn't always work correctly in all possible system configuration cases e.g. preloading, symbol interposition etc.
My opinion here is that upstream should remove the ability to run libc.so.6 as a binary.
User has /lib64/libdl-2.17.so in /etc/ld.so.preload They also have a subsystem that executes /lib64/libc.so and parse its output. The problem happens with new glibc: $ gdb /lib64/libc-2.17.so ... (gdb) set environment LD_PRELOAD=/lib64/libdl-2.17.so (gdb) run Starting program: /lib64/libc-2.17.so Program received signal SIGSEGV, Segmentation fault. strcpy () at ../sysdeps/x86_64/multiarch/strcpy.S:66 66 HAS_ARCH_FEATURE (Fast_Unaligned_Load) (gdb) bt #0 strcpy () at ../sysdeps/x86_64/multiarch/strcpy.S:66 #1 0x00007ffff7de76b8 in elf_machine_rela (reloc=0x7ffff7bd7bf8, reloc=0x7ffff7bd7bf8, skip_ifunc=<optimized out>, reloc_addr_arg=0x7ffff7dda038, version=<optimized out>, sym=0x7ffff7bd7368, map=0x7ffff7ff9658) at ../sysdeps/x86_64/dl-machine.h:308 #2 elf_dynamic_do_Rela (skip_ifunc=<optimized out>, lazy=<optimized out>, nrelative=<optimized out>, relsize=<optimized out>, reladdr=<optimized out>, map=0x7ffff7ff9658) at do-rel.h:137 #3 _dl_relocate_object (scope=<optimized out>, reloc_mode=<optimized out>, consider_profiling=<optimized out>, consider_profiling@entry=0) at dl-reloc.c:259 #4 0x00007ffff7ddf98a in dl_main (phdr=<optimized out>, phdr@entry=0x555555554040, phnum=<optimized out>, phnum@entry=10, user_entry=user_entry@entry=0x7fffffffde18, auxv=<optimized out>) at rtld.c:2179 Checking disassemble, it attempted to get _dl_x86_cpu_features address and check a bit on it. But it was a NULL pointer. (gdb) disassemble Dump of assembler code for function strcpy: 0x00005555555e07c0 <+0>: mov 0x33a681(%rip),%rdx # 0x55555591ae48 0x00005555555e07c7 <+7>: lea 0xdf12(%rip),%rax # 0x5555555ee6e0 <__strcpy_sse2_unaligned> => 0x00005555555e07ce <+14>: testl $0x10,0xb8(%rdx) (gdb) p *(void**) 0x55555591ae48 $1 = (void *) 0x0 From my understanding, it should have been the same as: (gdb) p _rtld_local_ro._dl_x86_cpu_features $2 = {kind = arch_kind_intel, max_cpuid = 13, cpuid = {{eax = 132769, ebx = 2048, ecx = 2679644675, edx = 126614527}, {eax = 0, ebx = 0, ecx = 0, edx = 0}, {eax = 0, ebx = 0, ecx = 0, edx = 0}}, family = 6, model = 42, xsave_state_size = 896, feature = {123}} (gdb) p& _rtld_local_ro._dl_x86_cpu_features $3 = (struct cpu_features *) 0x7ffff7ffcc70 <_rtld_local_ro+112> It should be required some code change to allow preloading libdl.so and 'executing' libc.so; executing a binary works, and it should be related to sysdeps/x86/libc-start.c: ... extern struct cpu_features _dl_x86_cpu_features; int __libc_start_main (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), int argc, char **argv, __typeof (main) init, void (*fini) (void), void (*rtld_fini) (void), void *stack_end) { init_cpu_features (&_dl_x86_cpu_features); return generic_start_main (main, argc, argv, init, fini, rtld_fini, stack_end); } ...