aarch64: morello: fix DL_SYMBOL_ADDRESS

It has to return a pointer that can be dereferenced, so it must be
derived correctly from RX and RW capabilities.

Try to have tight object bounds and seal function symbols.
This commit is contained in:
Szabolcs Nagy 2022-09-06 14:17:35 +01:00
parent 9912e5c608
commit ab0bc274aa
6 changed files with 84 additions and 2 deletions

View File

@ -9,7 +9,7 @@ LDFLAGS-rtld += -Wl,-z,force-bti,--fatal-warnings
endif
ifeq ($(subdir),elf)
sysdep-dl-routines += dl-bti
sysdep-dl-routines += dl-bti dl-symaddr
tests += tst-audit26 \
tst-audit27

View File

@ -22,6 +22,14 @@
struct link_map;
#ifdef __CHERI_PURE_CAPABILITY__
/* Symbol pointer with correct capability permission and bounds. */
void *_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref);
rtld_hidden_proto (_dl_symbol_address)
# define DL_SYMBOL_ADDRESS(map, ref) _dl_symbol_address(map, ref)
#endif
extern void _dl_unmap (struct link_map *map);
#define DL_UNMAP(map) _dl_unmap (map)

View File

@ -0,0 +1,17 @@
/* Empty file: AArch64 does not have special DL_SYMBOL_ADDRESS.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */

View File

@ -0,0 +1,6 @@
ld {
GLIBC_PRIVATE {
# in ld.so, but used by libc.so too.
_dl_symbol_address;
}
}

View File

@ -0,0 +1,49 @@
/* Get the symbol address. Morello version.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <ldsodefs.h>
#include <dl-machine.h>
void *
_dl_symbol_address (struct link_map *map, const ElfW(Sym) *ref)
{
elfptr_t value = SYMBOL_ADDRESS (map, ref, false);
if (map == NULL)
return (void *) value;
if (ELFW(ST_TYPE) (ref->st_info) == STT_OBJECT)
{
unsigned long perm_mask = CAP_PERM_MASK_R;
for (int i = 0; i < map->l_rw_count; i++)
if (map->l_rw_range[i].start <= value
&& map->l_rw_range[i].end > value)
{
value = dl_rw_ptr (map, value - map->l_addr);
perm_mask = CAP_PERM_MASK_RW;
break;
}
value = __builtin_cheri_bounds_set_exact (value, ref->st_size);
value = __builtin_cheri_perms_and (value, perm_mask);
}
else if (ELFW(ST_TYPE) (ref->st_info) == STT_FUNC)
{
/* Seal function pointers. Note: ifunc is handled by the caller. */
value = __builtin_cheri_seal_entry (value);
}
return (void *) value;
}
rtld_hidden_def (_dl_symbol_address)

View File

@ -140,8 +140,10 @@ typedef void (*dl_init_t) (int, char **, char **);
to the actual code of the function but rather an architecture
specific descriptor. */
#ifndef ELF_FUNCTION_PTR_IS_SPECIAL
# define DL_SYMBOL_ADDRESS(map, ref) \
# ifndef __CHERI_PURE_CAPABILITY__
# define DL_SYMBOL_ADDRESS(map, ref) \
(void *) SYMBOL_ADDRESS (map, ref, false)
# endif
# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
# define DL_CALL_DT_INIT(map, start, argc, argv, env) \
((dl_init_t) (start)) (argc, argv, env)