From 765e7ea59608e994a92f26ed11cfa4a432b31108 Mon Sep 17 00:00:00 2001 From: Andreas Ziegler Date: Tue, 4 Feb 2020 14:30:09 +0100 Subject: [PATCH] segments.py: fix TLS checks in section_in_segment() (#275) While the comment in section_in_segment() suggests that the logic follows the logic inside ELF_SECTION_IN_SEGMENT_1 with the strict parameter set, all of the checks in the binutils macro are written so that they must succeed for the section to be contained in the current segment. In our implementation, however, the checks were not properly negated. This showed in the case of .tdata and .tbss which did not appear in the section to segment mapping (these sections are found in glibc, for example). Fix it up by aligning the logic more closely to the binutils macro by implementing the same logic and returning False only if the checks fail. Additionally, introduce the third check from the upstream binutils which checks the combination of SHT_ALLOC sections and PT_LOAD-like segments. Furthermore, in the original check, the PT_GNU_RELRO type was misspelled with a 0 (zero) instead of an O so this check could never have worked. Fixes: #263 --- elftools/elf/segments.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/elftools/elf/segments.py b/elftools/elf/segments.py index 16560bc..0c318e1 100644 --- a/elftools/elf/segments.py +++ b/elftools/elf/segments.py @@ -40,15 +40,23 @@ class Segment(object): sectype = section['sh_type'] secflags = section['sh_flags'] - # Only PT_LOAD, PT_GNU_RELR0 and PT_TLS segments can contain SHF_TLS + # Only PT_LOAD, PT_GNU_RELRO and PT_TLS segments can contain SHF_TLS # sections if ( secflags & SH_FLAGS.SHF_TLS and - segtype in ('PT_TLS', 'PT_GNU_RELR0', 'PT_LOAD')): - return False + segtype in ('PT_TLS', 'PT_GNU_RELRO', 'PT_LOAD')): + pass # PT_TLS segment contains only SHF_TLS sections, PT_PHDR no sections # at all - elif ( (secflags & SH_FLAGS.SHF_TLS) != 0 and + elif ( (secflags & SH_FLAGS.SHF_TLS) == 0 and segtype not in ('PT_TLS', 'PT_PHDR')): + pass + else: + return False + + # PT_LOAD and similar segments only have SHF_ALLOC sections. + if ( (secflags & SH_FLAGS.SHF_ALLOC) == 0 and + segtype in ('PT_LOAD', 'PT_DYNAMIC', 'PT_GNU_EH_FRAME', + 'PT_GNU_RELRO', 'PT_GNU_STACK')): return False # In ELF_SECTION_IN_SEGMENT_STRICT the flag check_vma is on, so if -- 2.30.2