mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 21:40:12 +00:00
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:
parent
9912e5c608
commit
ab0bc274aa
@ -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
|
||||
|
@ -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)
|
||||
|
17
sysdeps/aarch64/dl-symaddr.c
Normal file
17
sysdeps/aarch64/dl-symaddr.c
Normal 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/>. */
|
6
sysdeps/aarch64/morello/Versions
Normal file
6
sysdeps/aarch64/morello/Versions
Normal file
@ -0,0 +1,6 @@
|
||||
ld {
|
||||
GLIBC_PRIVATE {
|
||||
# in ld.so, but used by libc.so too.
|
||||
_dl_symbol_address;
|
||||
}
|
||||
}
|
49
sysdeps/aarch64/morello/dl-symaddr.c
Normal file
49
sysdeps/aarch64/morello/dl-symaddr.c
Normal 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)
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user