cheri: elf: use RX, RW capabilities to derive pointers

Instead of

  map->l_addr + offset

use

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

depending on RX or RW permission requirement.
This commit is contained in:
Szabolcs Nagy 2022-08-08 13:03:57 +01:00
parent b35504abf0
commit 9c11d64d6d
13 changed files with 37 additions and 39 deletions

View File

@ -132,7 +132,7 @@ call_init (int argc, char **argv, char **env)
the same file. */ the same file. */
if (ELF_INITFINI && l->l_info[DT_INIT] != NULL) 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); argc, argv, env);
ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY]; 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 unsigned int jm
= l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (elfptr_t); = 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) for (unsigned int j = 0; j < jm; ++j)
((dl_init_t) addrs[j]) (argc, argv, env); ((dl_init_t) addrs[j]) (argc, argv, env);
} }

View File

@ -125,7 +125,7 @@ __libc_setup_tls (void)
/* Remember the values we need. */ /* Remember the values we need. */
memsz = phdr->p_memsz; memsz = phdr->p_memsz;
filesz = phdr->p_filesz; 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; align = phdr->p_align;
if (phdr->p_align > max_align) if (phdr->p_align > max_align)
max_align = phdr->p_align; max_align = phdr->p_align;

View File

@ -120,8 +120,7 @@ call_destructors (void *closure)
if (map->l_info[DT_FINI_ARRAY] != NULL) if (map->l_info[DT_FINI_ARRAY] != NULL)
{ {
elfptr_t *array = elfptr_t *array =
(elfptr_t *) (map->l_addr (elfptr_t *) dl_rx_ptr (map, map->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
+ map->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
unsigned int sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val unsigned int sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
/ sizeof (elfptr_t)); / sizeof (elfptr_t));
@ -131,8 +130,7 @@ call_destructors (void *closure)
/* Next try the old-style destructor. */ /* Next try the old-style destructor. */
if (map->l_info[DT_FINI] != NULL) if (map->l_info[DT_FINI] != NULL)
DL_CALL_DT_FINI (map, ((void *) map->l_addr DL_CALL_DT_FINI (map, dl_rx_ptr (map, map->l_info[DT_FINI]->d_un.d_ptr));
+ map->l_info[DT_FINI]->d_un.d_ptr));
} }
void void

View File

@ -105,7 +105,7 @@ _dl_find_object_from_map (struct link_map *l,
if (ph->p_type == DLFO_EH_SEGMENT_TYPE) if (ph->p_type == DLFO_EH_SEGMENT_TYPE)
{ {
atomic_store_relaxed (&result->eh_frame, 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 #if DLFO_STRUCT_HAS_EH_COUNT
atomic_store_relaxed (&result->eh_count, ph->p_memsz / 8); atomic_store_relaxed (&result->eh_count, ph->p_memsz / 8);
#endif #endif

View File

@ -133,9 +133,8 @@ _dl_fini (void)
/* First see whether an array is given. */ /* First see whether an array is given. */
if (l->l_info[DT_FINI_ARRAY] != NULL) if (l->l_info[DT_FINI_ARRAY] != NULL)
{ {
elfptr_t *array = ElfW(Addr) v = l->l_info[DT_FINI_ARRAY]->d_un.d_ptr;
(elfptr_t *) (l->l_addr elfptr_t *array = (elfptr_t *) dl_rx_ptr (l, v);
+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
/ sizeof (elfptr_t)); / sizeof (elfptr_t));
while (i-- > 0) while (i-- > 0)
@ -145,7 +144,7 @@ _dl_fini (void)
/* Next try the old-style destructor. */ /* Next try the old-style destructor. */
if (ELF_INITFINI && l->l_info[DT_FINI] != NULL) if (ELF_INITFINI && l->l_info[DT_FINI] != NULL)
DL_CALL_DT_FINI 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 #ifdef SHARED

View File

@ -53,7 +53,8 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
- the others in the DT_INIT_ARRAY. - the others in the DT_INIT_ARRAY.
*/ */
if (ELF_INITFINI && l->l_info[DT_INIT] != NULL) 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. */ /* Next see whether there is an array with initialization functions. */
ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY]; 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); 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) for (j = 0; j < jm; ++j)
((dl_init_t) addrs[j]) (argc, argv, env); ((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", _dl_debug_printf ("\ncalling preinit: %s\n\n",
DSO_FILENAME (main_map->l_name)); 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) for (cnt = 0; cnt < i; ++cnt)
((dl_init_t) addrs[cnt]) (argc, argv, env); ((dl_init_t) addrs[cnt]) (argc, argv, env);
} }

View File

@ -866,7 +866,7 @@ _dl_init_paths (const char *llp, const char *source,
void void
_dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph) _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) size = ph->p_memsz;
const ElfW(Addr) align = ph->p_align; 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 else
/* Adjust the PT_PHDR value by the runtime load address. */ /* 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)) 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. */ /* Adjust the address of the TLS initialization image. */
if (l->l_tls_initimage != NULL) 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 /* Process program headers again after load segments are mapped in
case processing requires accessing those segments. Scan program 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. */ /* If this is ET_EXEC, we should have loaded it as lt_executable. */
assert (type != ET_EXEC || l->l_type == 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)) if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
_dl_debug_printf ("\ _dl_debug_printf ("\

View File

@ -353,8 +353,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
void void
_dl_protect_relro (struct link_map *l) _dl_protect_relro (struct link_map *l)
{ {
elfptr_t start = ALIGN_DOWN((l->l_addr elfptr_t start = ALIGN_DOWN(dl_rx_ptr (l, l->l_relro_addr),
+ l->l_relro_addr),
GLRO(dl_pagesize)); GLRO(dl_pagesize));
elfptr_t end = ALIGN_DOWN((l->l_addr elfptr_t end = ALIGN_DOWN((l->l_addr
+ l->l_relro_addr + l->l_relro_addr

View File

@ -55,7 +55,7 @@ _dl_fixup (
+ reloc_offset (pltgot, reloc_arg)); + reloc_offset (pltgot, reloc_arg));
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
const ElfW(Sym) *refsym = sym; 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; lookup_t result;
DL_FIXUP_VALUE_TYPE value; DL_FIXUP_VALUE_TYPE value;

View 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; def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr;
assert (def_offset != 0); assert (def_offset != 0);
def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset); def = (ElfW(Verdef) *) dl_rx_ptr (map, def_offset);
while (1) while (1)
{ {
/* Currently the version number of the definition entry is 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) if (dyn != NULL)
{ {
/* This file requires special versions from its dependencies. */ /* 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. /* Currently the version number of the needed entry is 1.
Make sure all we see is this version. */ 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) if (def != NULL)
{ {
ElfW(Verdef) *ent; 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) while (1)
{ {
if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high) 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) if (dyn != NULL)
{ {
ElfW(Verneed) *ent; 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) while (1)
{ {
ElfW(Vernaux) *aux; ElfW(Vernaux) *aux;
@ -334,7 +334,7 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
if (def != NULL) if (def != NULL)
{ {
ElfW(Verdef) *ent; 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) while (1)
{ {
ElfW(Verdaux) *aux; ElfW(Verdaux) *aux;

View 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; ElfW (Half) ndx = version[ELFW (R_SYM) (r->r_info)] & 0x7fff;
const ElfW (Sym) *sym = &symtab[ELFW (R_SYM) (r->r_info)]; 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]; const struct r_found_version *rversion = &map->l_versions[ndx];
elf_machine_rel (map, scope, r, sym, rversion, r_addr_arg, skip_ifunc); 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; ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; 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]; const struct r_found_version *rversion = &map->l_versions[ndx];
#if defined ELF_MACHINE_IRELATIVE #if defined ELF_MACHINE_IRELATIVE
if (ELFW(R_TYPE) (r->r_info) == 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, elf_machine_rel (map, scope, r2,
&symtab[ELFW(R_SYM) (r2->r_info)], &symtab[ELFW(R_SYM) (r2->r_info)],
&map->l_versions[ndx], &map->l_versions[ndx],
(void *) (l_addr + r2->r_offset), (void *) dl_rw_ptr (map, r2->r_offset),
skip_ifunc); skip_ifunc);
} }
#endif #endif
@ -179,7 +179,7 @@ elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
for (; r < end; ++r) for (; r < end; ++r)
{ {
const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (r->r_info)]; 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 # ifdef ELF_MACHINE_IRELATIVE
if (ELFW(R_TYPE) (r->r_info) == 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) for (; r2 <= end2; ++r2)
if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)], 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); skip_ifunc);
# endif # endif
} }

View File

@ -723,8 +723,7 @@ match_version (const char *string, struct link_map *map)
/* The file has no symbol versioning. */ /* The file has no symbol versioning. */
return 0; return 0;
def = (ElfW(Verdef) *) ((char *) map->l_addr def = (ElfW(Verdef) *) dl_rx_ptr (map, map->l_info[VERDEFTAG]->d_un.d_ptr);
+ map->l_info[VERDEFTAG]->d_un.d_ptr);
while (1) while (1)
{ {
ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux); 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 dlopen call or DT_NEEDED entry, for something that wants to link
against the dynamic linker as a shared library, will know that against the dynamic linker as a shared library, will know that
the shared object is already loaded. */ the shared object is already loaded. */
_dl_rtld_libname.name = ((const char *) main_map->l_addr _dl_rtld_libname.name = (const char *) dl_rx_ptr (main_map,
+ ph->p_vaddr); ph->p_vaddr);
/* _dl_rtld_libname.next = NULL; Already zero. */ /* _dl_rtld_libname.next = NULL; Already zero. */
GL(dl_rtld_map).l_libname = &_dl_rtld_libname; 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. */ the executable is actually an ET_DYN object. */
if (main_map->l_tls_initimage != NULL) if (main_map->l_tls_initimage != NULL)
main_map->l_tls_initimage 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) if (! main_map->l_map_end)
main_map->l_map_end = ~0; main_map->l_map_end = ~0;
if (! main_map->l_text_end) if (! main_map->l_text_end)
@ -2252,7 +2251,7 @@ dl_main (const ElfW(Phdr) *phdr,
continue; continue;
strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); 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) if (first)
{ {

View 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 most architectures the entry is already relocated - but for some not
and we need to relocate at access time. */ and we need to relocate at access time. */
#define D_PTR(map, i) \ #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. */ /* Result of the lookup functions and how to retrieve the base address. */
typedef struct link_map *lookup_t; typedef struct link_map *lookup_t;