From patchwork Thu Jun 20 17:08:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Szabolcs Nagy X-Patchwork-Id: 33246 Received: (qmail 116417 invoked by alias); 20 Jun 2019 17:08:36 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 116409 invoked by uid 89); 20 Jun 2019 17:08:36 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-18.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.1 spammy=AUT, authenticates, aut X-HELO: EUR04-HE1-obe.outbound.protection.outlook.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RqAppwsUHfZoPH4RJ0f0WXY6NWPrL5yE5oAU34lZHd0=; b=sceRL3VVaYjSskoBtchk46NX+KvTCcFPUzDGcCW6USrt4COtTujYiEbkOmvIcxfFmae0YbfcLveWi+0lzhD88FaZwRqLRLmg7+duQFI2MsTHPRElH08u33WsCJuEX/dMzY//SoRi1F2xE5buAOQZXDaJQ85oJchS/cWV5M7E7nc= From: Szabolcs Nagy To: GNU C Library CC: nd , Sudakshina Das Subject: [PATCH 2/2] aarch64: Support PLT with PAC Date: Thu, 20 Jun 2019 17:08:30 +0000 Message-ID: <4d56a496-b06e-9cda-d3d8-d797ae8687b9@arm.com> References: <5ec73433-43c3-5e7a-62cb-a3b203cf41c5@arm.com> In-Reply-To: <5ec73433-43c3-5e7a-62cb-a3b203cf41c5@arm.com> user-agent: Mozilla/5.0 (X11; Linux aarch64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 authentication-results: spf=none (sender IP is ) smtp.mailfrom=Szabolcs.Nagy@arm.com; x-ms-oob-tlc-oobclassifiers: OLM:8882; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 MIME-Version: 1.0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Szabolcs.Nagy@arm.com Add pointer authentication code to the function pointers in PLTGOT if DT_AARCH64_PAC_PLT is set on an elf binary. In such binaries the PLT authenticates the pointer loaded from the GOT entry. This is only valid in LP64 binaries and only useful when the PLTGOT is writable at runtime, i.e. with lazy binding. Note: TLS descriptors are not protected, the static linker should ensure that GOT entries with TLSDESC relocations are read-only, i.e. they are not lazy resolved. 2019-06-20 Szabolcs Nagy * sysdeps/aarch64/dl-machine.h (set_jump_slot): Define. (elf_machine_fixup_plt): Use set_jump_slot. (elf_machine_rela): Likewise. (elf_machine_lazy_rel): Likewise. diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h index 4f27637b20..91c3db409b 100644 --- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -214,19 +214,36 @@ dl_platform_init (void) static executable. */ init_cpu_features (&GLRO(dl_aarch64_cpu_features)); #endif } +/* Set *RELOC_ADDR such that a PLT entry using it jumps to VALUE, this is + needed because the PLT entry may apply transformations before the jump. */ +static inline ElfW(Addr) +set_jump_slot (struct link_map *map, ElfW(Addr) *reloc_addr, ElfW(Addr) value) +{ +#ifdef __LP64__ + if (map->l_info[DT_AARCH64 (PAC_PLT)]) + { + /* Add PAC if the PLT uses AUT to verify the loaded pointer. */ + register Elf64_Addr *x16 asm ("x16") = reloc_addr; + register Elf64_Addr x17 asm ("x17") = value; + asm ("hint #0x8 // pacia1716" : "+r"(x17) : "r"(x16)); + value = x17; + } +#endif + return *reloc_addr = value; +} static inline ElfW(Addr) elf_machine_fixup_plt (struct link_map *map, lookup_t t, const ElfW(Sym) *refsym, const ElfW(Sym) *sym, const ElfW(Rela) *reloc, ElfW(Addr) *reloc_addr, ElfW(Addr) value) { - return *reloc_addr = value; + return set_jump_slot (map, reloc_addr, value); } /* Return the final value of a plt relocation. */ static inline ElfW(Addr) elf_machine_plt_value (struct link_map *map, @@ -288,13 +305,16 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, memcpy (reloc_addr_arg, (void *) value, sym->st_size < refsym->st_size ? sym->st_size : refsym->st_size); break; + case AARCH64_R(JUMP_SLOT): + set_jump_slot (map, reloc_addr, value + reloc->r_addend); + break; + case AARCH64_R(RELATIVE): case AARCH64_R(GLOB_DAT): - case AARCH64_R(JUMP_SLOT): case AARCH64_R(ABS32): #ifdef __LP64__ case AARCH64_R(ABS64): #endif *reloc_addr = value + reloc->r_addend; @@ -361,11 +381,11 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, break; case AARCH64_R(IRELATIVE): value = map->l_addr + reloc->r_addend; value = elf_ifunc_invoke (value); - *reloc_addr = value; + set_jump_slot (map, reloc_addr, value); break; default: _dl_reloc_bad_type (map, r_type, 0); break; @@ -396,11 +416,11 @@ elf_machine_lazy_rel (struct link_map *map, if (__builtin_expect (r_type == AARCH64_R(JUMP_SLOT), 1)) { if (map->l_mach.plt == 0) { /* Prelinking. */ - *reloc_addr += l_addr; + set_jump_slot (map, reloc_addr, *reloc_addr + l_addr); return; } if (__glibc_unlikely (map->l_mach.variant_pcs)) { @@ -423,11 +443,11 @@ elf_machine_lazy_rel (struct link_map *map, skip_ifunc); return; } } - *reloc_addr = map->l_mach.plt; + set_jump_slot (map, reloc_addr, map->l_mach.plt); } else if (__builtin_expect (r_type == AARCH64_R(TLSDESC), 1)) { const Elf_Symndx symndx = ELFW (R_SYM) (reloc->r_info); const ElfW (Sym) *symtab = (const void *)D_PTR (map, l_info[DT_SYMTAB]); @@ -448,11 +468,11 @@ elf_machine_lazy_rel (struct link_map *map, else if (__glibc_unlikely (r_type == AARCH64_R(IRELATIVE))) { ElfW(Addr) value = map->l_addr + reloc->r_addend; if (__glibc_likely (!skip_ifunc)) value = elf_ifunc_invoke (value); - *reloc_addr = value; + set_jump_slot (map, reloc_addr, value); } else _dl_reloc_bad_type (map, r_type, 1); }