diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-06-18 10:28:39 -0700 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2020-06-22 12:20:43 +0100 |
commit | 3be82491fa7d4ee9efd9118c5021e866c7ef3820 (patch) | |
tree | 2889d65e17dcd4e28164df0a2b8cbe67f91db536 | |
parent | 2fd3fdf54dcc9cf2c40808bf6b9b95a69038f929 (diff) | |
download | glibc-3be82491fa7d4ee9efd9118c5021e866c7ef3820.tar.gz glibc-3be82491fa7d4ee9efd9118c5021e866c7ef3820.tar.xz glibc-3be82491fa7d4ee9efd9118c5021e866c7ef3820.zip |
rtld: Rename _rtld_process_pt_note to _dl_process_pt_note
The old _dl_process_pt_note and _rtld_process_pt_note differ in how the program header is read. The old _dl_process_pt_note is called before PT_LOAD segments are mapped and _rtld_process_pt_note is called after PT_LOAD segments are mapped. Since PT_GNU_PROPERTY is processed after PT_LOAD segments are mapped, we can process PT_NOTE together with PT_GNU_PROPERTY. We can remove the old _dl_process_pt_note and rename _rtld_process_pt_note to _dl_process_pt_note. NOTE: We scan program headers backward so that PT_NOTE can be skipped if PT_GNU_PROPERTY exits.
-rw-r--r-- | elf/dl-load.c | 21 | ||||
-rw-r--r-- | elf/rtld.c | 18 | ||||
-rw-r--r-- | sysdeps/generic/dl-prop.h | 14 | ||||
-rw-r--r-- | sysdeps/x86/dl-prop.h | 44 |
4 files changed, 23 insertions, 74 deletions
diff --git a/elf/dl-load.c b/elf/dl-load.c index 66bd0ca0a3..32c74f79ef 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1216,14 +1216,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, l->l_relro_addr = ph->p_vaddr; l->l_relro_size = ph->p_memsz; break; - - case PT_NOTE: - if (_dl_process_pt_note (l, ph, fd, fbp)) - { - errstring = N_("cannot process note segment"); - goto call_lose; - } - break; } if (__glibc_unlikely (nloadcmds == 0)) @@ -1261,12 +1253,17 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, goto call_lose; /* Process program headers again after load segments are mapped in - case processing requires accessing those segments. */ - for (ph = phdr; ph < &phdr[l->l_phnum]; ++ph) - switch (ph->p_type) + case processing requires accessing those segments. Scan program + headers backward so that PT_NOTE can be skipped if PT_GNU_PROPERTY + exits. */ + for (ph = &phdr[l->l_phnum]; ph != phdr; --ph) + switch (ph[-1].p_type) { + case PT_NOTE: + _dl_process_pt_note (l, &ph[-1]); + break; case PT_GNU_PROPERTY: - _dl_process_pt_gnu_property (l, ph); + _dl_process_pt_gnu_property (l, &ph[-1]); break; } } diff --git a/elf/rtld.c b/elf/rtld.c index 3ad2bf5079..f4c2602d65 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1507,15 +1507,17 @@ of this helper program; chances are you did not intend to run this program.\n\ main_map->l_relro_addr = ph->p_vaddr; main_map->l_relro_size = ph->p_memsz; break; - - case PT_GNU_PROPERTY: - _dl_process_pt_gnu_property (main_map, ph); - break; - + } + /* Process program headers again, but scan them backwards so + that PT_NOTE can be skipped if PT_GNU_PROPERTY exits. */ + for (ph = &phdr[phnum]; ph != phdr; --ph) + switch (ph[-1].p_type) + { case PT_NOTE: - if (_rtld_process_pt_note (main_map, ph)) - _dl_error_printf ("\ -ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); + _dl_process_pt_note (main_map, &ph[-1]); + break; + case PT_GNU_PROPERTY: + _dl_process_pt_gnu_property (main_map, &ph[-1]); break; } diff --git a/sysdeps/generic/dl-prop.h b/sysdeps/generic/dl-prop.h index ceb6f623ee..f1cf576fe3 100644 --- a/sysdeps/generic/dl-prop.h +++ b/sysdeps/generic/dl-prop.h @@ -36,19 +36,9 @@ _dl_open_check (struct link_map *m) { } -#ifdef FILEBUF_SIZE -static inline int __attribute__ ((always_inline)) -_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph, - int fd, struct filebuf *fbp) -{ - return 0; -} -#endif - -static inline int __attribute__ ((always_inline)) -_rtld_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph) +static inline void __attribute__ ((always_inline)) +_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph) { - return 0; } /* Called for each property in the NT_GNU_PROPERTY_TYPE_0 note of L, diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h index 4a8ebc573e..89911e19e2 100644 --- a/sysdeps/x86/dl-prop.h +++ b/sysdeps/x86/dl-prop.h @@ -19,8 +19,6 @@ #ifndef _DL_PROP_H #define _DL_PROP_H -#include <not-cancel.h> - extern void _dl_cet_check (struct link_map *, const char *) attribute_hidden; extern void _dl_cet_open_check (struct link_map *) @@ -146,49 +144,11 @@ _dl_process_cet_property_note (struct link_map *l, #endif } -#ifdef FILEBUF_SIZE -static inline int __attribute__ ((unused)) -_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph, - int fd, struct filebuf *fbp) -{ -# if CET_ENABLED - const ElfW(Nhdr) *note; - ElfW(Nhdr) *note_malloced = NULL; - ElfW(Addr) size = ph->p_filesz; - - if (ph->p_offset + size <= (size_t) fbp->len) - note = (const void *) (fbp->buf + ph->p_offset); - else - { - if (size < __MAX_ALLOCA_CUTOFF) - note = alloca (size); - else - { - note_malloced = malloc (size); - note = note_malloced; - } - if (__pread64_nocancel (fd, (void *) note, size, ph->p_offset) != size) - { - if (note_malloced) - free (note_malloced); - return -1; - } - } - - _dl_process_cet_property_note (l, note, size, ph->p_align); - if (note_malloced) - free (note_malloced); -# endif - return 0; -} -#endif - -static inline int __attribute__ ((unused)) -_rtld_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph) +static inline void __attribute__ ((unused)) +_dl_process_pt_note (struct link_map *l, const ElfW(Phdr) *ph) { const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr); _dl_process_cet_property_note (l, note, ph->p_memsz, ph->p_align); - return 0; } static inline int __attribute__ ((always_inline)) |