Bug 2297186 - glibc: The name recorded in the link_map does not match what is returned by dladdr
Summary: glibc: The name recorded in the link_map does not match what is returned by d...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 40
Hardware: Unspecified
OS: Linux
unspecified
medium
Target Milestone: ---
Assignee: Carlos O'Donell
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2024-07-10 18:48 UTC by Ben Woodard
Modified: 2025-05-20 19:22 UTC (History)
14 users (show)

Fixed In Version: glibc-2.40.9000-23.fc42
Clone Of:
Environment:
Last Closed: 2025-05-20 19:12:21 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
reproducer (1.31 KB, application/gzip)
2024-07-10 18:51 UTC, Ben Woodard
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker RHEL-47467 0 None None None 2024-07-16 06:57:08 UTC

Description Ben Woodard 2024-07-10 18:48:17 UTC
When tools are inspecting the actual link_map of an application the l_name, the value of the main application is left blank and so consequently doesn't match what is returned by dlinfo(3).

These need to match for tools to be able run without having to implement all kinds of special case logic. 

The first problem is when the la_objopen() auditor function is called it is passed an empty string for the object's name. This really should be populated with the name of the file being opened as it is in almost all other cases. This empty name is then what is stored in the link_map->l_name entry.  Subsequently, when dlinfo(3) is called then it surprisingly is able to identify the object's name. 

The problem as reported is that they do not match but it appears that the underlying problem is that the l_name field is not populated properly hen the original executable is first loaded.

There is a secondary problem as well, the base address of a non-pie executable is recorded as NULL rather than at its actual address as loaded.

Reproducible: Always

Steps to Reproduce:
1. tar xvzf inconsistent-objopen.tar.gz
2. cd inconsistent-objopen/
3. make
Actual Results:  
$ make

Success requires OK (not FAIL) at the end of output:
LD_AUDIT=./libauditor-vdso.so ./main-simple
  la_objopen('')
  la_objopen('/lib64/ld-linux-x86-64.so.2')
  la_objopen('linux-vdso.so.1')
    Seen vDSO from objopen!
  la_objopen('/lib64/libc.so.6')
la_preinit, scanning main link_map...
  l_name = ''
  l_name = 'linux-vdso.so.1'
    Seen vDSO in link map!
  l_name = '/lib64/libc.so.6'
  l_name = '/lib64/ld-linux-x86-64.so.2'
dladdr(vDSO) pathname matches link_map entry. OK.
dladdr(vDSO) base address matches link_map entry. OK.
vDSO notified via objopen. OK.

Success requires OK (not FAIL) at the end of output:
./main-dlinfo-pie
Name recorded in Dl_info:  './main-dlinfo-pie' at base 0x556ac1fbd000
Name recorded in link_map: '' at base 0x556ac1fbd000
Pathnames do not match. FAIL.
Base addresses match. OK.
./main-dlinfo-nopie
Name recorded in Dl_info:  './main-dlinfo-nopie' at base 0x400000
Name recorded in link_map: '' at base (nil)
Pathnames do not match. FAIL.
Base addresses do not match. FAIL.

Expected Results:  
$ make

Success requires OK (not FAIL) at the end of output:
LD_AUDIT=./libauditor-vdso.so ./main-simple
  la_objopen('./main-simple')
  la_objopen('/lib64/ld-linux-x86-64.so.2')
  la_objopen('linux-vdso.so.1')
    Seen vDSO from objopen!
  la_objopen('/lib64/libc.so.6')
la_preinit, scanning main link_map...
  l_name = './main-simple'
  l_name = 'linux-vdso.so.1'
    Seen vDSO in link map!
  l_name = '/lib64/libc.so.6'
  l_name = '/lib64/ld-linux-x86-64.so.2'
dladdr(vDSO) pathname matches link_map entry. OK.
dladdr(vDSO) base address matches link_map entry. OK.
vDSO notified via objopen. OK.

Success requires OK (not FAIL) at the end of output:
./main-dlinfo-pie
Name recorded in Dl_info:  './main-dlinfo-pie' at base 0x556ac1fbd000
Name recorded in link_map: './main-dlinfo-pie' at base 0x556ac1fbd000
Pathnames do not match. OK.
Base addresses match. OK.
./main-dlinfo-nopie
Name recorded in Dl_info:  './main-dlinfo-nopie' at base 0x400000
Name recorded in link_map: ''./main-dlinfo-nopie at base 0x400000
Pathnames do not match. OK.
Base addresses do not match. OK.

Comment 1 Ben Woodard 2024-07-10 18:51:39 UTC
Created attachment 2039426 [details]
reproducer

Comment 2 Florian Weimer 2024-07-16 07:00:30 UTC
I do not think we will be able to change the glibc behavior here. Let's keep this bug open to track the corresponding manual update. We should document what glibc is doing, together with a rationale (which might be considered weak, admittedly).

Comment 3 Ben Woodard 2024-07-16 14:00:47 UTC
(In reply to Florian Weimer from comment #2)
> I do not think we will be able to change the glibc behavior here. Let's keep
> this bug open to track the corresponding manual update. We should document
> what glibc is doing, together with a rationale (which might be considered
> weak, admittedly).

Why is that? 

A change in behavior like this that makes information like l_name consistent seems like it would be acceptable for a minor release along with documentation describing the change.

The base address problem for non-PIE binaries seems to be very clearly a bug though. I cannot imagine any rational for that being considered the "correct" behavior.

Comment 4 Carlos O'Donell 2024-08-16 13:47:52 UTC
v4 is upstream, with changes requested:
https://inbox.sourceware.org/libc-alpha/875xsagf4f.fsf@oldenburg.str.redhat.com/T/#t

Comment 5 Carlos O'Donell 2024-09-06 13:51:15 UTC
v5 is upstream, and needs review:
https://patchwork.sourceware.org/project/glibc/patch/87bk14iuew.fsf@oldenburg.str.redhat.com/

Comment 6 Aoife Moloney 2025-04-28 13:29:37 UTC
This message is a reminder that Fedora Linux 40 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora Linux 40 on 2025-05-13.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
'version' of '40'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, change the 'version' 
to a later Fedora Linux version. Note that the version field may be hidden.
Click the "Show advanced fields" button if you do not see it.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora Linux 40 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora Linux, you are encouraged to change the 'version' to a later version
prior to this bug being closed.

Comment 7 Aoife Moloney 2025-05-20 19:12:21 UTC
Fedora Linux 40 entered end-of-life (EOL) status on 2025-05-13.

Fedora Linux 40 is no longer maintained, which means that it
will not receive any further security or bug fix updates. As a result we
are closing this bug.

If you can reproduce this bug against a currently maintained version of Fedora Linux
please feel free to reopen this bug against that version. Note that the version
field may be hidden. Click the "Show advanced fields" button if you do not see
the version field.

If you are unable to reopen this bug, please file a new report against an
active release.

Thank you for reporting this bug and we are sorry it could not be fixed.

Comment 8 Florian Weimer 2025-05-20 19:22:06 UTC
Upstream commit:

commit b7d4de086ce7fcc531cdd67a61dc27b5b3eff482
Author: Florian Weimer <fweimer>
Date:   Mon Aug 5 16:01:12 2024 +0200

    manual: Describe struct link_map, support link maps with dlinfo
    
    This does not describe how to use RTLD_DI_ORIGIN and l_name
    to reconstruct a full path for the an object. The reason
    is that I think we should not recommend further use of
    RTLD_DI_ORIGIN due to its buffer overflow potential (bug 24298).
    This should be covered by another dlinfo extension.  It would
    also obsolete the need for the dladdr approach to obtain
    the file name for the main executable.
    
    Obtaining the lowest address from load segments in program
    headers is quite clumsy and should be provided directly
    via dlinfo.
    
    Reviewed-by: Carlos O'Donell <carlos>

This went into glibc-2.40.9000-23.fc42.


Note You need to log in before you can comment on or make changes to this bug.