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.

Bug 1887974

Summary: crash running libc while loading libdl
Product: Red Hat Enterprise Linux 7 Reporter: Paulo Andrade <pandrade>
Component: glibcAssignee: glibc team <glibc-bugzilla>
Status: CLOSED DUPLICATE QA Contact: qe-baseos-tools-bugs
Severity: medium Docs Contact:
Priority: unspecified    
Version: 7.8CC: ashankar, codonell, dj, fweimer, mnewsome, pfrankli, sipoyare
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2020-10-15 13:36:09 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Paulo Andrade 2020-10-13 17:16:49 UTC
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 2 Siddhesh Poyarekar 2020-10-15 13:36:09 UTC
See bug 1428369 comment 10 for the rationale for not fixing this.

*** This bug has been marked as a duplicate of bug 1428369 ***

Comment 3 Paulo Andrade 2020-10-22 13:00:19 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".

Comment 4 Carlos O'Donell 2020-10-22 15:48:16 UTC
(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.