Malformed phdrs in separated debuginfo
by Florian Weimer
On 02/12/2014 01:36 PM, Mark Wielaard wrote:
> On Wed, 2014-02-12 at 13:14 +0100, Florian Weimer wrote:
>> Here's the original issue I ran into: Separate debugging information,
>> for example the file /usr/lib/debug/usr/lib64/libdl-2.18.so.debug in
>> package glibc-debuginfo-2.18-12.fc20.x86_64, often contains garbage as
>> the program interpreter:
>>
>> $ eu-readelf -a /usr/lib/debug/usr/lib64/libdl-2.18.so.debug | grep
>> Requesting | xxd
>> 0000000: 095b 5265 7175 6573 7469 6e67 2070 726f .[Requesting pro
>> 0000010: 6772 616d 2069 6e74 6572 7072 6574 6572 gram interpreter
>> 0000020: 3a20 0608 bf14 5d0a : ....].
>>
>> Is this a known issue with debuginfo separation? Should I report this
>> somewhere?
>
> Aha. Yeah, the issue is that the phdr doesn't really make sense for a
> separate debuginfo file. It isn't really a loadable ELF file. Only the
> shdrs make sense, since the debuginfo sections are accessed through. In
> theory [eu]-strip could just remove the phdrs, but some tools do expect
> them to be there and we do sometimes use them to make sure the original
> (stripped) ELF file and the debug file match (eu-unstrip will only
> reconstruct the original ELF file, putting the debuginfo back in, if the
> phdrs match up for example).
>
> If you look with eu-readelf -l you'll see the mapping form phdr segments
> (which would be how an ELF file is mapped into memory) to the shdr
> sections. e.g.
>
> Program Headers:
> Type Offset VirtAddr PhysAddr FileSiz
> MemSiz Flg Align
> PHDR 0x000040 0x00000033c8e00040 0x00000033c8e00040 0x0001f8
> 0x0001f8 R E 0x8
> INTERP 0x001a50 0x00000033c8e01a50 0x00000033c8e01a50 0x00001c
> 0x00001c R 0x10
> [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
> [...]
> Section to Segment mapping:
> Segment Sections...
> 00
> 01 [RO: .interp]
> [...]
>
> The problem in the .debug file is that the sections on disk that map to
> loadable segments have been replaced with NOBITS. eu-readelf -S on the
> debug file will give:
>
> [16] .interp NOBITS 0000000000001a50 00000280
> 0000001c 0 A 0 0 16
>
> But when eu-readelf tries to display the content of the PT_INTERP
> segment it doesn't know that, so it tries to print the content anyway.
>
> Separate debuginfo files stretch the ELF concept a little. I'll have to
> think about how to handle this nicely and/or how we can detect that the
> phdrs aren't to be trusted in this case.
Is there a reliable way to recognize separate debugging information?
Then I could avoid extracting data from phdrs.
--
Florian Weimer / Red Hat Product Security Team
10 years
[PATCH] libdwfl: linux-proc-maps.c (proc_maps_report): Don't assert on bad input.
by Mark Wielaard
If ino == last_ino && dmajor == last_dmajor && dminor == last_dminor then
we expect the file names to be the same as well. Which is reasonable if
the input came from the /proc file system. But there could be bad user
input if the file was supplied through dwfl_linux_proc_maps_report.
Instead of asserting on the bad input, just signal a bad_report.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdwfl/ChangeLog | 4 ++++
libdwfl/linux-proc-maps.c | 3 ++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index e55b03b..7d25330 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
+2014-02-26 Mark Wielaard <mjw(a)redhat.com>
+
+ * linux-proc-maps.c (proc_maps_report): Don't assert on bad input.
+
2014-01-17 Petr Machata <pmachata(a)redhat.com>
* relocate.c (relocate_section): Use gelf_fsize instead of relying
diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c
index cdb6959..a52920c 100644
--- a/libdwfl/linux-proc-maps.c
+++ b/libdwfl/linux-proc-maps.c
@@ -241,7 +241,8 @@ proc_maps_report (Dwfl *dwfl, FILE *f, GElf_Addr sysinfo_ehdr, pid_t pid)
&& ino == last_ino && dmajor == last_dmajor && dminor == last_dminor)
{
/* This is another portion of the same file's mapping. */
- assert (!strcmp (last_file, file));
+ if (strcmp (last_file, file) != 0)
+ goto bad_report;
high = end;
}
else
--
1.8.5.3
10 years