]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
cheri: elf: use RX, RW capabilities to derive pointers
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Mon, 8 Aug 2022 12:03:57 +0000 (13:03 +0100)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 12 Oct 2022 13:22:03 +0000 (14:22 +0100)
Instead of

  map->l_addr + offset

use

  dl_rx_ptr (map, offset)
  dl_rw_ptr (map, offset)

depending on RX or RW permission requirement.

13 files changed:
csu/libc-start.c
csu/libc-tls.c
elf/dl-close.c
elf/dl-find_object.h
elf/dl-fini.c
elf/dl-init.c
elf/dl-load.c
elf/dl-reloc.c
elf/dl-runtime.c
elf/dl-version.c
elf/do-rel.h
elf/rtld.c
sysdeps/generic/ldsodefs.h

index 2acefceb1ae7a23e74cccb6707af863a4e96c24e..d71fbec3fe0cc0d355d20bd00425598c7d224077 100644 (file)
@@ -132,7 +132,7 @@ call_init (int argc, char **argv, char **env)
      the same file.  */
 
   if (ELF_INITFINI && l->l_info[DT_INIT] != NULL)
-    DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr,
+    DL_CALL_DT_INIT(l, dl_rx_ptr (l, l->l_info[DT_INIT]->d_un.d_ptr),
                    argc, argv, env);
 
   ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
@@ -140,7 +140,7 @@ call_init (int argc, char **argv, char **env)
     {
       unsigned int jm
        = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (elfptr_t);
-      elfptr_t *addrs = (void *) (init_array->d_un.d_ptr + l->l_addr);
+      elfptr_t *addrs = (void *) dl_rx_ptr (l, init_array->d_un.d_ptr);
       for (unsigned int j = 0; j < jm; ++j)
        ((dl_init_t) addrs[j]) (argc, argv, env);
     }
index b3d146472d047252b265697cda72baa3b2e63e31..0701ec5acb91b228809c3ff813bf62ab905cb32b 100644 (file)
@@ -125,7 +125,7 @@ __libc_setup_tls (void)
          /* Remember the values we need.  */
          memsz = phdr->p_memsz;
          filesz = phdr->p_filesz;
-         initimage = phdr->p_vaddr + (void *) main_map->l_addr;
+         initimage = (void *) dl_rx_ptr (main_map, phdr->p_vaddr);
          align = phdr->p_align;
          if (phdr->p_align > max_align)
            max_align = phdr->p_align;
index a20cf8cc36f7c4ec8668e75545dde76e765fdc7f..5a45062f099822563fa94d0f2199dfa06fd08422 100644 (file)
@@ -120,8 +120,7 @@ call_destructors (void *closure)
   if (map->l_info[DT_FINI_ARRAY] != NULL)
     {
       elfptr_t *array =
-       (elfptr_t *) (map->l_addr
-                       + map->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
+       (elfptr_t *) dl_rx_ptr (map, map->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
       unsigned int sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
                         / sizeof (elfptr_t));
 
@@ -131,8 +130,7 @@ call_destructors (void *closure)
 
   /* Next try the old-style destructor.  */
   if (map->l_info[DT_FINI] != NULL)
-    DL_CALL_DT_FINI (map, ((void *) map->l_addr
-                          + map->l_info[DT_FINI]->d_un.d_ptr));
+    DL_CALL_DT_FINI (map, dl_rx_ptr (map, map->l_info[DT_FINI]->d_un.d_ptr));
 }
 
 void
index 3b49877e0e8448a24c20b54dcbf8a5ac14a6d190..a4df9a7d67e1d7e40ece5c780a54eeb0b4c0e337 100644 (file)
@@ -105,7 +105,7 @@ _dl_find_object_from_map (struct link_map *l,
     if (ph->p_type == DLFO_EH_SEGMENT_TYPE)
       {
         atomic_store_relaxed (&result->eh_frame,
-                              (void *) (ph->p_vaddr + l->l_addr));
+                              (void *) dl_rx_ptr (l, ph->p_vaddr));
 #if DLFO_STRUCT_HAS_EH_COUNT
         atomic_store_relaxed (&result->eh_count, ph->p_memsz / 8);
 #endif
index 040bda28b265c5fc9c64c32eee57864bc10547f5..18135b2191b911a12f3850301f30c24eb422d883 100644 (file)
@@ -133,9 +133,8 @@ _dl_fini (void)
                      /* First see whether an array is given.  */
                      if (l->l_info[DT_FINI_ARRAY] != NULL)
                        {
-                         elfptr_t *array =
-                           (elfptr_t *) (l->l_addr
-                                           + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
+                         ElfW(Addr) v = l->l_info[DT_FINI_ARRAY]->d_un.d_ptr;
+                         elfptr_t *array = (elfptr_t *) dl_rx_ptr (l, v);
                          unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
                                            / sizeof (elfptr_t));
                          while (i-- > 0)
@@ -145,7 +144,7 @@ _dl_fini (void)
                      /* Next try the old-style destructor.  */
                      if (ELF_INITFINI && l->l_info[DT_FINI] != NULL)
                        DL_CALL_DT_FINI
-                         (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr);
+                         (l, dl_rx_ptr (l, l->l_info[DT_FINI]->d_un.d_ptr));
                    }
 
 #ifdef SHARED
index 4c8aaae7e0c2d21b8154fe01f51929e9a1f5fa0c..7fb2af6a3f433f744b60bb7514b1d058d22835ac 100644 (file)
@@ -53,7 +53,8 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
      - the others in the DT_INIT_ARRAY.
   */
   if (ELF_INITFINI && l->l_info[DT_INIT] != NULL)
-    DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
+    DL_CALL_DT_INIT(l, dl_rx_ptr (l, l->l_info[DT_INIT]->d_un.d_ptr),
+                   argc, argv, env);
 
   /* Next see whether there is an array with initialization functions.  */
   ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
@@ -65,7 +66,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
 
       jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (elfptr_t);
 
-      addrs = (elfptr_t *) (init_array->d_un.d_ptr + l->l_addr);
+      addrs = (elfptr_t *) dl_rx_ptr (l, init_array->d_un.d_ptr);
       for (j = 0; j < jm; ++j)
        ((dl_init_t) addrs[j]) (argc, argv, env);
     }
@@ -97,7 +98,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env)
        _dl_debug_printf ("\ncalling preinit: %s\n\n",
                          DSO_FILENAME (main_map->l_name));
 
-      addrs = (elfptr_t *) (preinit_array->d_un.d_ptr + main_map->l_addr);
+      addrs = (elfptr_t *) dl_rx_ptr (main_map, preinit_array->d_un.d_ptr);
       for (cnt = 0; cnt < i; ++cnt)
        ((dl_init_t) addrs[cnt]) (argc, argv, env);
     }
index 192ad4f7c9305dfd2b09b18995a681966e27a764..b25ddaec0568a08d11f6b623e4b5738281f393b0 100644 (file)
@@ -866,7 +866,7 @@ _dl_init_paths (const char *llp, const char *source,
 void
 _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
 {
-  const ElfW(Nhdr) *note = (const void *) (ph->p_vaddr + l->l_addr);
+  const ElfW(Nhdr) *note = (const void *) dl_rx_ptr (l, ph->p_vaddr);
   const ElfW(Addr) size = ph->p_memsz;
   const ElfW(Addr) align = ph->p_align;
 
@@ -1316,7 +1316,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
     }
   else
     /* Adjust the PT_PHDR value by the runtime load address.  */
-    l->l_phdr = (ElfW(Phdr) *) ((ElfW(Addr)) l->l_phdr + l->l_addr);
+    l->l_phdr = (ElfW(Phdr) *) dl_rx_ptr (l, (ElfW(Addr)) l->l_phdr);
 
   if (__glibc_unlikely ((stack_flags &~ GL(dl_stack_flags)) & PF_X))
     {
@@ -1371,7 +1371,8 @@ cannot enable executable stack as shared object requires");
 
   /* Adjust the address of the TLS initialization image.  */
   if (l->l_tls_initimage != NULL)
-    l->l_tls_initimage = (ElfW(Addr)) l->l_tls_initimage + (char *) l->l_addr;
+    l->l_tls_initimage
+      = (void *) dl_rw_ptr (l, (ElfW(Addr)) l->l_tls_initimage);
 
   /* Process program headers again after load segments are mapped in
      case processing requires accessing those segments.  Scan program
@@ -1404,7 +1405,7 @@ cannot enable executable stack as shared object requires");
   /* If this is ET_EXEC, we should have loaded it as lt_executable.  */
   assert (type != ET_EXEC || l->l_type == lt_executable);
 
-  l->l_entry += l->l_addr;
+  l->l_entry = dl_rx_ptr (l, l->l_entry);
 
   if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
     _dl_debug_printf ("\
index abc72472baaf9aafc01241c225e6f3a2e45b3d4e..d0d9a51716ec02c527b7dfdaf5cf9e3b9eda227d 100644 (file)
@@ -353,8 +353,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 void
 _dl_protect_relro (struct link_map *l)
 {
-  elfptr_t start = ALIGN_DOWN((l->l_addr
-                                + l->l_relro_addr),
+  elfptr_t start = ALIGN_DOWN(dl_rx_ptr (l, l->l_relro_addr),
                                GLRO(dl_pagesize));
   elfptr_t end = ALIGN_DOWN((l->l_addr
                               + l->l_relro_addr
index e7c99cbc82f0797d50ef749d91c891adfdb33778..5f6aef3e62e17e71ff16b50ab689d079f4d6b241 100644 (file)
@@ -55,7 +55,7 @@ _dl_fixup (
                      + reloc_offset (pltgot, reloc_arg));
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   const ElfW(Sym) *refsym = sym;
-  void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
+  void *const rel_addr = (void *) dl_rw_ptr (l, reloc->r_offset);
   lookup_t result;
   DL_FIXUP_VALUE_TYPE value;
 
index cda08892098e2ade19a85f8d96775baa7cc7ffad..f19c8d1b42bc512552612dda3bc2bdbfe8498c50 100644 (file)
@@ -86,7 +86,7 @@ checking for version `%s' in file %s [%lu] required by file %s [%lu]\n",
   def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr;
   assert (def_offset != 0);
 
-  def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset);
+  def = (ElfW(Verdef) *) dl_rx_ptr (map, def_offset);
   while (1)
     {
       /* Currently the version number of the definition entry is 1.
@@ -177,7 +177,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
   if (dyn != NULL)
     {
       /* This file requires special versions from its dependencies.  */
-      ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+      ElfW(Verneed) *ent = (ElfW(Verneed) *) dl_rx_ptr (map, dyn->d_un.d_ptr);
 
       /* Currently the version number of the needed entry is 1.
         Make sure all we see is this version.  */
@@ -257,7 +257,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
   if (def != NULL)
     {
       ElfW(Verdef) *ent;
-      ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr);
+      ent = (ElfW(Verdef) *) dl_rx_ptr (map, def->d_un.d_ptr);
       while (1)
        {
          if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high)
@@ -296,7 +296,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (dyn != NULL)
        {
          ElfW(Verneed) *ent;
-         ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+         ent = (ElfW(Verneed) *) dl_rx_ptr (map, dyn->d_un.d_ptr);
          while (1)
            {
              ElfW(Vernaux) *aux;
@@ -334,7 +334,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
       if (def != NULL)
        {
          ElfW(Verdef) *ent;
-         ent = (ElfW(Verdef)  *) (map->l_addr + def->d_un.d_ptr);
+         ent = (ElfW(Verdef)  *) dl_rx_ptr (map, def->d_un.d_ptr);
          while (1)
            {
              ElfW(Verdaux) *aux;
index 0c028ca8b3b18f6195b985768f75e2a146686fd5..0a2eddf73710f4afa9e8d520e2f71e2519ec6ada 100644 (file)
@@ -62,7 +62,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
     {
       ElfW (Half) ndx = version[ELFW (R_SYM) (r->r_info)] & 0x7fff;
       const ElfW (Sym) *sym = &symtab[ELFW (R_SYM) (r->r_info)];
-      void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+      void *const r_addr_arg = (void *) dl_rw_ptr (map, r->r_offset);
       const struct r_found_version *rversion = &map->l_versions[ndx];
 
       elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, skip_ifunc);
@@ -132,7 +132,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
            {
              ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
              const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
-             void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+             void *const r_addr_arg = (void *) dl_rw_ptr (map, r->r_offset);
              const struct r_found_version *rversion = &map->l_versions[ndx];
 #if defined ELF_MACHINE_IRELATIVE
              if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
@@ -169,7 +169,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
                  elf_machine_rel (map, scope, r2,
                                   &symtab[ELFW(R_SYM) (r2->r_info)],
                                   &map->l_versions[ndx],
-                                  (void *) (l_addr + r2->r_offset),
+                                  (void *) dl_rw_ptr (map, r2->r_offset),
                                   skip_ifunc);
                }
 #endif
@@ -179,7 +179,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
          for (; r < end; ++r)
            {
              const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)];
-             void *const r_addr_arg = (void *) (l_addr + r->r_offset);
+             void *const r_addr_arg = (void *) dl_rw_ptr (map, r->r_offset);
 # ifdef ELF_MACHINE_IRELATIVE
              if (ELFW(R_TYPE) (r->r_info) == ELF_MACHINE_IRELATIVE)
                {
@@ -210,7 +210,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
            for (; r2 <= end2; ++r2)
              if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
                elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
-                                NULL, (void *) (l_addr + r2->r_offset),
+                                NULL, (void *) dl_rw_ptr (map, r2->r_offset),
                                 skip_ifunc);
 # endif
        }
index fcb8b9e888f72843e0f452e2cd7ca8c57b0734bc..82e40e82013ad0c3611fc22c1c3b72f6fae98ca3 100644 (file)
@@ -723,8 +723,7 @@ match_version (const char *string, struct link_map *map)
     /* The file has no symbol versioning.  */
     return 0;
 
-  def = (ElfW(Verdef) *) ((char *) map->l_addr
-                         + map->l_info[VERDEFTAG]->d_un.d_ptr);
+  def = (ElfW(Verdef) *) dl_rx_ptr (map, map->l_info[VERDEFTAG]->d_un.d_ptr);
   while (1)
     {
       ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux);
@@ -1193,8 +1192,8 @@ rtld_setup_main_map (struct link_map *main_map)
           dlopen call or DT_NEEDED entry, for something that wants to link
           against the dynamic linker as a shared library, will know that
           the shared object is already loaded.  */
-       _dl_rtld_libname.name = ((const char *) main_map->l_addr
-                                + ph->p_vaddr);
+       _dl_rtld_libname.name = (const char *) dl_rx_ptr (main_map,
+                                                         ph->p_vaddr);
        /* _dl_rtld_libname.next = NULL;        Already zero.  */
        GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
 
@@ -1311,7 +1310,7 @@ rtld_setup_main_map (struct link_map *main_map)
      the executable is actually an ET_DYN object.  */
   if (main_map->l_tls_initimage != NULL)
     main_map->l_tls_initimage
-      = (ElfW(Addr)) main_map->l_tls_initimage + (char *) main_map->l_addr;
+      = (void *) dl_rx_ptr (main_map, (ElfW(Addr)) main_map->l_tls_initimage);
   if (! main_map->l_map_end)
     main_map->l_map_end = ~0;
   if (! main_map->l_text_end)
@@ -2252,7 +2251,7 @@ dl_main (const ElfW(Phdr) *phdr,
                    continue;
 
                  strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
-                 ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
+                 ent = (ElfW(Verneed) *) dl_rx_ptr (map, dyn->d_un.d_ptr);
 
                  if (first)
                    {
index 0cc9d7e89c661ede10fc12971a6f341a76d02df0..8c930e9493a39d6ba1aeca4ebe23f7e74f1841a3 100644 (file)
@@ -115,7 +115,8 @@ dl_rw_ptr (const struct link_map *l, ElfW(Addr) vaddr)
   most architectures the entry is already relocated - but for some not
   and we need to relocate at access time.  */
 #define D_PTR(map, i) \
-  ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_addr))
+  (dl_relocate_ld (map) ? (map)->i->d_un.d_ptr \
+                       : dl_rx_ptr ((map), (map)->i->d_un.d_ptr))
 
 /* Result of the lookup functions and how to retrieve the base address.  */
 typedef struct link_map *lookup_t;