diff mbox series

[v5,08/14] rtld: Rename _rtld_process_pt_note to _dl_process_pt_note

Message ID 3be82491fa7d4ee9efd9118c5021e866c7ef3820.1592834304.git.szabolcs.nagy@arm.com
State New
Headers show
Series aarch64: branch protection support | expand

Commit Message

Szabolcs Nagy June 22, 2020, 2 p.m. UTC
From: "H.J. Lu" <hjl.tools@gmail.com>

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.
---
 elf/dl-load.c             | 21 ++++++++-----------
 elf/rtld.c                | 18 +++++++++-------
 sysdeps/generic/dl-prop.h | 14 ++-----------
 sysdeps/x86/dl-prop.h     | 44 ++-------------------------------------
 4 files changed, 23 insertions(+), 74 deletions(-)
diff mbox series

Patch

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))