You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
3.4 KiB
70 lines
3.4 KiB
From ea011ddb65272c74d6378deae3f3a3365aadd77d Mon Sep 17 00:00:00 2001
|
|
From: Romain Geissler <romain.geissler@amadeus.com>
|
|
Date: Tue, 20 Jun 2023 16:06:31 +0000
|
|
Subject: [PATCH] elf-util: discard PT_LOAD segment early based on the start
|
|
address.
|
|
|
|
Indeed when iterating over all the PT_LOAD segment of the core dump
|
|
while trying to look for the elf headers of a given module, we iterate
|
|
over them all and try to use the first one for which we can parse a
|
|
package metadata, but the start address is never taken into account,
|
|
so absolutely nothing guarantees we actually parse the right ELF header
|
|
of the right module we are currently iterating on.
|
|
|
|
This was tested like this:
|
|
- Create a core dump using sleep on a fedora 37 container, with an
|
|
explicit LD_PRELOAD of a library having a valid package metadata:
|
|
|
|
podman run -t -i --rm -v $(pwd):$(pwd) -w $(pwd) fedora:37 bash -x -c \
|
|
'LD_PRELOAD=libreadline.so.8 sleep 1000 & SLEEP_PID="$!" && sleep 1 && kill -11 "${SLEEP_PID}" && mv "core.${SLEEP_PID}" the-core'
|
|
|
|
- Then from a fedora 38 container with systemd installed, the resulting
|
|
core dump has been passed to systemd-coredump with and without this
|
|
patch. Without this patch, we get:
|
|
|
|
Module /usr/bin/sleep from rpm bash-5.2.15-3.fc38.x86_64
|
|
Module /usr/lib64/libtinfo.so.6.3 from rpm coreutils-9.1-8.fc37.x86_64
|
|
Module /usr/lib64/libc.so.6 from rpm coreutils-9.1-8.fc37.x86_64
|
|
Module /usr/lib64/libreadline.so.8.2 from rpm coreutils-9.1-8.fc37.x86_64
|
|
Module /usr/lib64/ld-linux-x86-64.so.2 from rpm coreutils-9.1-8.fc37.x86_64
|
|
|
|
While with this patch we get:
|
|
|
|
Module /usr/bin/sleep from rpm bash-5.2.15-3.fc38.x86_64
|
|
Module /usr/lib64/libtinfo.so.6.3 from rpm ncurses-6.3-5.20220501.fc37.x86_64
|
|
Module /usr/lib64/libreadline.so.8.2 from rpm readline-8.2-2.fc37.x86_64
|
|
|
|
So the parsed package metadata reported by systemd-coredump when the module
|
|
files are not found on the host (ie the case of crash inside a container) are
|
|
now correct. The inconsistency of the first module in the above example
|
|
(sleep is indeed not provided by the bash package) can be ignored as it
|
|
is a consequence of how this was tested.
|
|
|
|
In addition to this, this also fixes the performance issue of
|
|
systemd-coredump in case of the crashing process uses a large number of
|
|
shared libraries and having no package metadata, as reported in
|
|
https://sourceware.org/pipermail/elfutils-devel/2023q2/006225.html.
|
|
|
|
(cherry picked from commit 21a2c735e2bfdc3bfdc42f894d6e3d00f4a38dcd)
|
|
|
|
Resolves: #2222259
|
|
---
|
|
src/shared/elf-util.c | 4 ++++
|
|
1 file changed, 4 insertions(+)
|
|
|
|
diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c
|
|
index 181735409d..d746f3ab3f 100644
|
|
--- a/src/shared/elf-util.c
|
|
+++ b/src/shared/elf-util.c
|
|
@@ -538,6 +538,10 @@ static int module_callback(Dwfl_Module *mod, void **userdata, const char *name,
|
|
if (!program_header || program_header->p_type != PT_LOAD)
|
|
continue;
|
|
|
|
+ /* This PT_LOAD segment doesn't contain the start address, so it can't be the module we are looking for. */
|
|
+ if (start < program_header->p_vaddr || start >= program_header->p_vaddr + program_header->p_memsz)
|
|
+ continue;
|
|
+
|
|
/* Now get a usable Elf reference, and parse the notes from it. */
|
|
data = sym_elf_getdata_rawchunk(elf,
|
|
program_header->p_offset,
|