From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1944) id ECFA13850854; Wed, 12 Oct 2022 14:17:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ECFA13850854 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1665584276; bh=21ZGOziyFk85xkLlrk+eqp7827uUUxp5xh8wJEHUSio=; h=From:To:Subject:Date:From; b=hfP28zvSKYzM6jCmcFrdgug9ntW5Z3/4NwNrE3tYMkZRjThwObxSMY043AXLEEjFk Th8ryTceJ9oy9TF0wnRz+/EgLAEjNjp56cLPxe3HdIwkeEJr2F879iErMd9WGKgFi8 JrTvUjRsqMh3SanZi5ZComGKmndBx4P7iHYg7cUo= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Szabolcs Nagy To: glibc-cvs@sourceware.org Subject: [glibc/arm/morello/main] aarch64: morello: fix DL_SYMBOL_ADDRESS X-Act-Checkin: glibc X-Git-Author: Szabolcs Nagy X-Git-Refname: refs/heads/arm/morello/main X-Git-Oldrev: 9912e5c608b276588a0e83926353c0632f516a02 X-Git-Newrev: ab0bc274aaeb554748106eac0a6c68864085bfc4 Message-Id: <20221012141756.ECFA13850854@sourceware.org> Date: Wed, 12 Oct 2022 14:17:56 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ab0bc274aaeb554748106eac0a6c68864085bfc4 commit ab0bc274aaeb554748106eac0a6c68864085bfc4 Author: Szabolcs Nagy Date: Tue Sep 6 14:17:35 2022 +0100 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. Diff: --- sysdeps/aarch64/Makefile | 2 +- sysdeps/aarch64/dl-lookupcfg.h | 8 ++++++ sysdeps/aarch64/dl-symaddr.c | 17 +++++++++++++ sysdeps/aarch64/morello/Versions | 6 +++++ sysdeps/aarch64/morello/dl-symaddr.c | 49 ++++++++++++++++++++++++++++++++++++ sysdeps/generic/ldsodefs.h | 4 ++- 6 files changed, 84 insertions(+), 2 deletions(-) diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile index d50384c47b..9d6e16f66e 100644 --- a/sysdeps/aarch64/Makefile +++ b/sysdeps/aarch64/Makefile @@ -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 diff --git a/sysdeps/aarch64/dl-lookupcfg.h b/sysdeps/aarch64/dl-lookupcfg.h index 64d46a050e..aa3e50d46f 100644 --- a/sysdeps/aarch64/dl-lookupcfg.h +++ b/sysdeps/aarch64/dl-lookupcfg.h @@ -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) diff --git a/sysdeps/aarch64/dl-symaddr.c b/sysdeps/aarch64/dl-symaddr.c new file mode 100644 index 0000000000..a85969a8f5 --- /dev/null +++ b/sysdeps/aarch64/dl-symaddr.c @@ -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 + . */ diff --git a/sysdeps/aarch64/morello/Versions b/sysdeps/aarch64/morello/Versions new file mode 100644 index 0000000000..d6c306bcbe --- /dev/null +++ b/sysdeps/aarch64/morello/Versions @@ -0,0 +1,6 @@ +ld { + GLIBC_PRIVATE { + # in ld.so, but used by libc.so too. + _dl_symbol_address; + } +} diff --git a/sysdeps/aarch64/morello/dl-symaddr.c b/sysdeps/aarch64/morello/dl-symaddr.c new file mode 100644 index 0000000000..b49b416170 --- /dev/null +++ b/sysdeps/aarch64/morello/dl-symaddr.c @@ -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 + . */ + +#include +#include + +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) diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 3cb35dbb93..0cc9d7e89c 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -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)