From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1944) id CF7723851523; Thu, 27 Oct 2022 13:59:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CF7723851523 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1666879148; bh=/HyX5W/jWrg4bAs2uJXLQXbUA32oP98b0wvODUqr2Io=; h=From:To:Subject:Date:From; b=OJPpCnNK9WoMlgbpzx02wg8GfOvI4jJCH6K5RnKcMqf4ARfdRSy7nfapuCE+zSvO3 Lihmbvym33ClMT0hwmC2dC4r9zTXVkziiU+HS94JY5am7fGzargH00MqNUIYgYCziN xhWDFdpp8cOBfNu0DAsr2WrLWlH0QrYqT+piYtBs= 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: c62607b9006c23b2f21f1bc5b36b048ce93071ec X-Git-Newrev: 63aa755b4064a0cbd1598b53cb8c82ecb8ea4e2d Message-Id: <20221027135908.CF7723851523@sourceware.org> Date: Thu, 27 Oct 2022 13:59:08 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=63aa755b4064a0cbd1598b53cb8c82ecb8ea4e2d commit 63aa755b4064a0cbd1598b53cb8c82ecb8ea4e2d 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 | 0 sysdeps/aarch64/morello/Versions | 6 +++++ sysdeps/aarch64/morello/dl-symaddr.c | 49 ++++++++++++++++++++++++++++++++++++ sysdeps/generic/ldsodefs.h | 4 ++- 6 files changed, 67 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..e69de29bb2 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 81b6356460..54316b7477 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -141,8 +141,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)