From patchwork Mon Feb 7 23:51:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 50898 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 50B47385841E for ; Mon, 7 Feb 2022 23:54:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 50B47385841E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1644278079; bh=T1ZBB+8EwB1HMxslR5eygKyePEiFzdXgpA94me6p3hY=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Wmk/OA01R7kdZW7pPMH6ci0zb+Fbq4CbvijqgEtwbxuPTQkWX/BablDAB/qtbuFNk xwNjrcQivbvX8q70yASZ8V8Iy4vQSJGawEAGJGAc+ROoWDN95TtSmT77eXbbx29Ar5 iIyYcNKqL5w2L+FTWWnk1GzWmnPyP6s7WyTKE3D0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by sourceware.org (Postfix) with ESMTPS id B83143858407 for ; Mon, 7 Feb 2022 23:51:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B83143858407 Received: by mail-pf1-x433.google.com with SMTP id g8so5923823pfq.9 for ; Mon, 07 Feb 2022 15:51:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=T1ZBB+8EwB1HMxslR5eygKyePEiFzdXgpA94me6p3hY=; b=suVfdfJRrOSO+WhpaMwMf7TL80z5rrZb9O9dnSyvw/lYxuTwIuRsFG2J0NYk62tjHL 67v9JqFbR5Hl4O9VxYinhQVz/N/jj7r5zOI3qku5n3C1hVdilmHBADIvY/c7fgJ58XG8 Z61iM8BhgO6SWPwWxh3MaKpdQhLhpGx/kHvJz3o2RvOaLIICMcbM8ZrbGeNkSBPa3orv CGBlzlfXKceBKdSBjQrosWU6bV4FSgwTfU5FCRgHDAOfr511WHhUb1mcOpN/8mmXtar0 X/Veg7YZP6U8+YRZ/MoZq72EI451DHsCIKTeI34ytzEBrQ0Oe6YsDWMR1iMhEI5WUgNs QMFQ== X-Gm-Message-State: AOAM530hWhYv9ztn2/mq7EERP/aI6vo7tZt0aqj+15IZq338W6fBZkom hIQc8OV4lte0tjWW1POsGwOqjj3NhvM= X-Google-Smtp-Source: ABdhPJygIac/MHqOnGD2tANrRwVmQjuMAykwRAcBXRxhuqP1tIDwzNBHO79PQaz9UY5Z/4yLsOU3ew== X-Received: by 2002:aa7:95b2:: with SMTP id a18mr1721583pfk.39.1644277890600; Mon, 07 Feb 2022 15:51:30 -0800 (PST) Received: from gnu-tgl-2.localdomain ([172.58.38.240]) by smtp.gmail.com with ESMTPSA id j5sm463641pjs.45.2022.02.07.15.51.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Feb 2022 15:51:28 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id 9B5643007E1; Mon, 7 Feb 2022 15:51:27 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v3 1/5] elf: Support DT_RELR relative relocation format [BZ #27924] Date: Mon, 7 Feb 2022 15:51:23 -0800 Message-Id: <20220207235127.1807294-2-hjl.tools@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207235127.1807294-1-hjl.tools@gmail.com> References: <20220207235127.1807294-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Joseph Myers Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" From: Fangrui Song PIE and shared objects usually have many relative relocations. In 2017/2018, SHT_RELR/DT_RELR was proposed on https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/GxjM0L-PBAAJ ("Proposal for a new section type SHT_RELR") and is a pre-standard. RELR usually takes 3% or smaller space than R_*_RELATIVE relocations. The virtual memory size of a mostly statically linked PIE is typically 5~10% smaller. --- Notes I will not include in the submitted commit: Available on https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/relr "pre-standard": even Solaris folks are happy with the refined generic-abi proposal. Cary Coutant will apply the change https://sourceware.org/pipermail/libc-alpha/2021-October/131781.html This patch is simpler than Chrome OS's glibc patch and makes ELF_DYNAMIC_DO_RELR available to all ports. I don't think the current glibc implementation supports ia64 in an ELFCLASS32 container. That said, the style I used is works with an ELFCLASS32 container for 64-bit machine if ElfW(Addr) is 64-bit. * Chrome OS folks have carried a local patch since 2018 (latest version: https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/refs/heads/main/sys-libs/glibc/files/local/glibc-2.32). I.e. this feature has been battle tested. * Android bionic supports 2018 and switched to DT_RELR==36 in 2020. * The Linux kernel has supported CONFIG_RELR since 2019-08 (https://git.kernel.org/linus/5cf896fb6be3effd9aea455b22213e27be8bdb1d). * A musl patch (by me) exists but is not applied: https://www.openwall.com/lists/musl/2019/03/06/3 * rtld-elf from FreeBSD 14 will support DT_RELR. I believe upstream glibc should support DT_RELR to benefit all Linux distributions. I filed some feature requests to get their attention: * Gentoo: https://bugs.gentoo.org/818376 * Arch Linux: https://bugs.archlinux.org/task/72433 * Debian https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=996598 * Fedora https://bugzilla.redhat.com/show_bug.cgi?id=2014699 As of linker support (to the best of my knowledge): * LLD support DT_RELR. * https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/refs/heads/main/sys-devel/binutils/files/ has a gold patch. * GNU ld feature request https://sourceware.org/bugzilla/show_bug.cgi?id=27923 Changes from the original patch: 1. Check the linker option, -z pack-relative-relocs, which add a GLIBC_ABI_DT_RELR symbol version dependency on the shared C library if it provides a GLIBC_2.XX symbol version. 2. Change make variale to have-dt-relr. 3. Rename tst-relr-no-pie to tst-relr-pie for --disable-default-pie. 4. Use TEST_VERIFY in tst-relr.c. 5. Add the check-tst-relr-pie.out test to check for linker generated libc.so version dependency on GLIBC_ABI_DT_RELR. --- configure | 42 +++++++++++++++++++++++++++ configure.ac | 10 +++++++ elf/Makefile | 14 +++++++++ elf/dynamic-link.h | 34 ++++++++++++++++++++++ elf/elf.h | 13 +++++++-- elf/get-dynamic-info.h | 3 ++ elf/tst-relr-pie.c | 1 + elf/tst-relr.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 elf/tst-relr-pie.c create mode 100644 elf/tst-relr.c diff --git a/configure b/configure index 8e5bee775a..9156e29fe9 100755 --- a/configure +++ b/configure @@ -6115,6 +6115,48 @@ $as_echo "$libc_linker_feature" >&6; } config_vars="$config_vars have-depaudit = $libc_cv_depaudit" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z pack-relative-relocs" >&5 +$as_echo_n "checking for linker that supports -z pack-relative-relocs... " >&6; } +libc_linker_feature=no +if test x"$gnu_ld" = x"yes"; then + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,pack-relative-relocs -nostdlib \ + -nostartfiles -fPIC -shared -o conftest.so conftest.c 2>&1 \ + | grep "warning: -z pack-relative-relocs ignored" > /dev/null 2>&1; then + true + else + libc_linker_feature=yes + fi + fi + rm -f conftest* +fi +if test $libc_linker_feature = yes; then + libc_cv_dt_relr=yes +else + libc_cv_dt_relr=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5 +$as_echo "$libc_linker_feature" >&6; } +config_vars="$config_vars +have-dt-relr = $libc_cv_dt_relr" +if test "$libc_cv_dt_relr" = yes; then + have_dt_relr=1 +else + have_dt_relr=0 +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports --no-dynamic-linker" >&5 $as_echo_n "checking for linker that supports --no-dynamic-linker... " >&6; } libc_linker_feature=no diff --git a/configure.ac b/configure.ac index 87f67d25ec..5c09871fee 100644 --- a/configure.ac +++ b/configure.ac @@ -1367,6 +1367,16 @@ LIBC_LINKER_FEATURE([--depaudit], [-Wl,--depaudit,x], [libc_cv_depaudit=yes], [libc_cv_depaudit=no]) LIBC_CONFIG_VAR([have-depaudit], [$libc_cv_depaudit]) +LIBC_LINKER_FEATURE([-z pack-relative-relocs], + [-Wl,-z,pack-relative-relocs], + [libc_cv_dt_relr=yes], [libc_cv_dt_relr=no]) +LIBC_CONFIG_VAR([have-dt-relr], [$libc_cv_dt_relr]) +if test "$libc_cv_dt_relr" = yes; then + have_dt_relr=1 +else + have_dt_relr=0 +fi + LIBC_LINKER_FEATURE([--no-dynamic-linker], [-Wl,--no-dynamic-linker], [libc_cv_no_dynamic_linker=yes], diff --git a/elf/Makefile b/elf/Makefile index ac37159b89..71b08c75dd 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -537,6 +537,14 @@ tests-special += \ # tests-special endif endif +ifeq ($(have-dt-relr),yes) +tests += tst-relr tst-relr-pie +tests-pie += tst-relr-pie +tests-special += $(objpfx)check-tst-relr-pie.out +CFLAGS-tst-relr-pie.c += $(pie-ccflag) +LDFLAGS-tst-relr += -Wl,-z,pack-relative-relocs +LDFLAGS-tst-relr-pie += -Wl,-z,pack-relative-relocs +endif endif ifeq ($(run-built-tests),yes) @@ -2733,3 +2741,9 @@ $(objpfx)tst-p_align3: $(objpfx)tst-p_alignmod3.so $(objpfx)tst-p_align3.out: tst-p_align3.sh $(objpfx)tst-p_align3 $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \ $(evaluate-test) + +$(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie + LC_ALL=C $(OBJDUMP) -p $< \ + | sed -ne '/required from libc.so/,$$ p' \ + | grep GLIBC_ABI_DT_RELR > $@; \ + $(evaluate-test) diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 25dd7ca4f2..5318079bac 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -146,14 +146,48 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], # define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */ # endif +# define ELF_DYNAMIC_DO_RELR(map) \ + do { \ + ElfW(Addr) l_addr = (map)->l_addr, *where = 0; \ + const ElfW(Relr) *r, *end; \ + if (!(map)->l_info[DT_RELR]) \ + break; \ + r = (const ElfW(Relr) *)D_PTR((map), l_info[DT_RELR]); \ + end = (const ElfW(Relr) *)((const char *)r + \ + (map)->l_info[DT_RELRSZ]->d_un.d_val); \ + for (; r < end; r++) \ + { \ + ElfW(Relr) entry = *r; \ + if ((entry & 1) == 0) \ + { \ + where = (ElfW(Addr) *)(l_addr + entry); \ + *where++ += l_addr; \ + } \ + else \ + { \ + for (long i = 0; (entry >>= 1) != 0; i++) \ + if ((entry & 1) != 0) \ + where[i] += l_addr; \ + where += CHAR_BIT * sizeof(ElfW(Relr)) - 1; \ + } \ + } \ + } while (0); + /* This can't just be an inline function because GCC is too dumb to inline functions containing inlines themselves. */ +# ifdef RTLD_BOOTSTRAP +# define DO_RTLD_BOOTSTRAP 1 +# else +# define DO_RTLD_BOOTSTRAP 0 +# endif # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \ do { \ int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \ (consider_profile)); \ ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \ ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \ + if (((map) != &GL(dl_rtld_map) || DO_RTLD_BOOTSTRAP)) \ + ELF_DYNAMIC_DO_RELR (map); \ } while (0) #endif diff --git a/elf/elf.h b/elf/elf.h index 0735f6b579..0195029188 100644 --- a/elf/elf.h +++ b/elf/elf.h @@ -443,7 +443,8 @@ typedef struct #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ #define SHT_GROUP 17 /* Section group */ #define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ -#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_RELR 19 /* RELR relative relocations */ +#define SHT_NUM 20 /* Number of defined types. */ #define SHT_LOOS 0x60000000 /* Start OS-specific. */ #define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ #define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ @@ -662,6 +663,11 @@ typedef struct Elf64_Sxword r_addend; /* Addend */ } Elf64_Rela; +/* RELR relocation table entry */ + +typedef Elf32_Word Elf32_Relr; +typedef Elf64_Xword Elf64_Relr; + /* How to extract and insert information held in the r_info field. */ #define ELF32_R_SYM(val) ((val) >> 8) @@ -887,7 +893,10 @@ typedef struct #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ #define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */ -#define DT_NUM 35 /* Number used */ +#define DT_RELRSZ 35 /* Total size of RELR relative relocations */ +#define DT_RELR 36 /* Address of RELR relative relocations */ +#define DT_RELRENT 37 /* Size of one RELR relative relocaction */ +#define DT_NUM 38 /* Number used */ #define DT_LOOS 0x6000000d /* Start of OS-specific */ #define DT_HIOS 0x6ffff000 /* End of OS-specific */ #define DT_LOPROC 0x70000000 /* Start of processor-specific */ diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h index 6c2ccd6db4..6c2a3a12b1 100644 --- a/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h @@ -89,6 +89,7 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap, # if ! ELF_MACHINE_NO_REL ADJUST_DYN_INFO (DT_REL); # endif + ADJUST_DYN_INFO (DT_RELR); ADJUST_DYN_INFO (DT_JMPREL); ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); @@ -113,6 +114,8 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap, if (info[DT_REL] != NULL) assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); #endif + if (info[DT_RELR] != NULL) + assert (info[DT_RELRENT]->d_un.d_val == sizeof (ElfW(Relr))); if (bootstrap || static_pie_bootstrap) { assert (info[DT_RUNPATH] == NULL); diff --git a/elf/tst-relr-pie.c b/elf/tst-relr-pie.c new file mode 100644 index 0000000000..7df0cdbfd6 --- /dev/null +++ b/elf/tst-relr-pie.c @@ -0,0 +1 @@ +#include "tst-relr.c" diff --git a/elf/tst-relr.c b/elf/tst-relr.c new file mode 100644 index 0000000000..56addd2ad4 --- /dev/null +++ b/elf/tst-relr.c @@ -0,0 +1,64 @@ +/* Basic tests for DT_RELR. + 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 +#include + +static int o, x; + +#define ELEMS O O O O O O O O X X X X X X X O O X O O X X X E X E E O X O E +#define E 0, + +#define O &o, +#define X &x, +void *arr[] = { ELEMS }; +#undef O +#undef X + +#define O 1, +#define X 2, +static char val[] = { ELEMS }; + +static int +do_test (void) +{ + ElfW(Dyn) *d = _DYNAMIC; + if (d) + { + bool has_relr = false; + for (; d->d_tag != DT_NULL; d++) + if (d->d_tag == DT_RELR) + has_relr = true; + +#if defined __PIE__ || defined __pie__ || defined PIE || defined pie + TEST_VERIFY (has_relr); +#else + TEST_VERIFY (!has_relr); +#endif + } + + for (int i = 0; i < sizeof (arr) / sizeof (arr[0]); i++) + TEST_VERIFY ((arr[i] == 0 && val[i] == 0) + || (arr[i] == &o && val[i] == 1) + || (arr[i] == &x && val[i] == 2)); + + return 0; +} + +#include From patchwork Mon Feb 7 23:51:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 50894 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 93B2C3858425 for ; Mon, 7 Feb 2022 23:51:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 93B2C3858425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1644277911; bh=1fjRhNEnzjQsUZyUMjOWpwJc4iw9bZRKwEZ1NpN4CL0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=VktvO4LokuNeoURLJ6h3KLacHx3aCjrejGwbufHwEGVtRdIgP1O76knAlViqqx0fg qmFeYv51acEeop86LpIAbI5LwxWotT7PQpcl7f5vvtH8eloHastsn6p56StUvD246u +cFnQfv1eYW5W3yqEZ7thvXUN2stdIcQSgURGE5M= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by sourceware.org (Postfix) with ESMTPS id CCE043858C2D for ; Mon, 7 Feb 2022 23:51:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CCE043858C2D Received: by mail-pj1-x1029.google.com with SMTP id g15-20020a17090a67cf00b001b7d5b6bedaso866252pjm.4 for ; Mon, 07 Feb 2022 15:51:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1fjRhNEnzjQsUZyUMjOWpwJc4iw9bZRKwEZ1NpN4CL0=; b=i8VmYw5BxU82W5EO+SXaqIgFQO2Vuvb9dsoSucPInn6OShYVI0NWjcKDSpoqbn2y/a pDcO3XVxL4muhSbeG0LvfVCZLTed5PPM9s7/4Mwa9cSZXYFprK1gwV+/3EwOMf+uk3py iU84Dtnq7/pbuGB3TS/8Kl1xv6LtAUy6R0FVxuuR+vip/QF6qp9rwZjDn6B+8cjy2Tjg nmKN2sMVAaXUjJ2tL2FTN35my5E0zKl8xhRQGC0nFDbf66KyO7iJ98CA5BwOPdanUj3q AhZY8dRSXejm6gLhgVmBuKo2earQGECJWZDlbi+seVJDGMJ3y0Q8oLKUa971GBClu5iS yyDg== X-Gm-Message-State: AOAM531VFC5xEw6psUC7HqYgxx33eUtzMleqkXEZiTT46L51zBjPusj8 7vJKlclVFHuIkLfgeO8SQZNHJr3VTKE= X-Google-Smtp-Source: ABdhPJzZjCejlNxHMnJL9BhNKcxbwZxLjE5EPtFlE8HVd7XmyeGKSXZsI31R0teEMWh6rJ0OrRhUYg== X-Received: by 2002:a17:90b:1806:: with SMTP id lw6mr1488178pjb.82.1644277889832; Mon, 07 Feb 2022 15:51:29 -0800 (PST) Received: from gnu-tgl-2.localdomain ([172.58.38.240]) by smtp.gmail.com with ESMTPSA id u18sm435548pjn.49.2022.02.07.15.51.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Feb 2022 15:51:28 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id A722C3007E3; Mon, 7 Feb 2022 15:51:27 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v3 2/5] elf: Properly handle zero DT_RELA/DT_REL values Date: Mon, 7 Feb 2022 15:51:24 -0800 Message-Id: <20220207235127.1807294-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207235127.1807294-1-hjl.tools@gmail.com> References: <20220207235127.1807294-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3029.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Joseph Myers Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" With DT_RELR, there may be no relocations in DT_RELA/DT_REL and their entry values are zero. Don't relocate DT_RELA/DT_REL and update the combined relocation start address if their entry values are zero. --- elf/dynamic-link.h | 6 +++++- elf/get-dynamic-info.h | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 5318079bac..320a9029f2 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -84,7 +84,9 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \ ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \ \ - if ((map)->l_info[DT_##RELOC]) \ + /* With DT_RELR, DT_RELA/DT_REL can have zero value. */ \ + if ((map)->l_info[DT_##RELOC] \ + && (map)->l_info[DT_##RELOC]->d_un.d_ptr != 0) \ { \ ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \ ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \ @@ -98,6 +100,8 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \ ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ \ + if (ranges[0].start == 0) \ + ranges[0].start = start; \ if (ranges[0].start + ranges[0].size == (start + size)) \ ranges[0].size -= size; \ if (!(do_lazy) \ diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h index 6c2a3a12b1..f4b957684b 100644 --- a/elf/get-dynamic-info.h +++ b/elf/get-dynamic-info.h @@ -83,16 +83,26 @@ elf_get_dynamic_info (struct link_map *l, bool bootstrap, ADJUST_DYN_INFO (DT_PLTGOT); ADJUST_DYN_INFO (DT_STRTAB); ADJUST_DYN_INFO (DT_SYMTAB); + ADJUST_DYN_INFO (DT_RELR); + ADJUST_DYN_INFO (DT_JMPREL); + ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); + ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); +# undef ADJUST_DYN_INFO + + /* DT_RELA/DT_REL are mandatory. But they may have zero value if + there is DT_RELR. Don't relocate them if they are zero. */ +# define ADJUST_DYN_INFO(tag) \ + do \ + if (info[tag] != NULL && info[tag]->d_un.d_ptr != 0) \ + info[tag]->d_un.d_ptr += l_addr; \ + while (0) + # if ! ELF_MACHINE_NO_RELA ADJUST_DYN_INFO (DT_RELA); # endif # if ! ELF_MACHINE_NO_REL ADJUST_DYN_INFO (DT_REL); # endif - ADJUST_DYN_INFO (DT_RELR); - ADJUST_DYN_INFO (DT_JMPREL); - ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM)); - ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH)); # undef ADJUST_DYN_INFO } if (info[DT_PLTREL] != NULL) From patchwork Mon Feb 7 23:51:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 50895 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 72958385841F for ; Mon, 7 Feb 2022 23:52:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 72958385841F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1644277953; bh=M+Bv0okUpH5SiBFDo4EWW6yHRqdb9G7d9VWJLw44usM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=xOXbG7UenhdYRtTdVXEKTAo409gmr1f+lKBVod4Bc4xn4PxBv0CtpYZJ9JOgtpt7x MwC9pskeWgtrswEO67xOmIrggs2IPvcUa1sC68DkPJdFZF2s1Bxgif1BJwK4A0y2vR MOksgHlPm4izU09NQE9n70+QpSOuh96Aa9XjQdy4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 9C4A13858C27 for ; Mon, 7 Feb 2022 23:51:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9C4A13858C27 Received: by mail-pl1-x629.google.com with SMTP id t9so10186170plg.13 for ; Mon, 07 Feb 2022 15:51:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=M+Bv0okUpH5SiBFDo4EWW6yHRqdb9G7d9VWJLw44usM=; b=7sUl6NaPDc4xtc3AlZZFsp0pbXyZGfaFtz4+PK9orJqoKLFto2F9rYIPaRM68t1UNb sLzeKRRA2DXvA3Jqu6BCf0WEbuAOH8/HYCNwysnw7nzB/sxrk6ylnCBLz66Wems02BGi NuM5foY4V/KKh0G5qJuCMIv+d2WDz3Ay5X6dKulAMXlwllOjGAave4tLXCQH9xUIRG1E YZ+JE3UowfCO+7wsLHAD+DvYRRuLHFR2S5y1gJMCcYSSTfbChXXRA6dKLpJOqL3eRI2u xdtzi8Qyeb//4MLZBBFzTcSCfMJaSofk22aRz6/83UVZNLXrmz+XQbf993/6XSDyTzP3 /r0Q== X-Gm-Message-State: AOAM532mdN3HNayPC2iMEU20SDOKw5S1stdPHA9RoDTEjzpJrsGZuOQo ghU5pQ6eR7lofmy2ploF4e8= X-Google-Smtp-Source: ABdhPJyJCSIP1Namdm4MDSj0RU6Gk1+c2v4PO11uMjX9COdW2+ROOwuPTrWwxHK4qiGn+QqmYsR6Gw== X-Received: by 2002:a17:90a:ea94:: with SMTP id h20mr1417365pjz.199.1644277889269; Mon, 07 Feb 2022 15:51:29 -0800 (PST) Received: from gnu-tgl-2.localdomain ([172.58.38.240]) by smtp.gmail.com with ESMTPSA id dw20sm458768pjb.3.2022.02.07.15.51.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Feb 2022 15:51:28 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id B31C53007E4; Mon, 7 Feb 2022 15:51:27 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v3 3/5] Add GLIBC_ABI_DT_RELR for DT_RELR support Date: Mon, 7 Feb 2022 15:51:25 -0800 Message-Id: <20220207235127.1807294-4-hjl.tools@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207235127.1807294-1-hjl.tools@gmail.com> References: <20220207235127.1807294-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Joseph Myers Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The EI_ABIVERSION field of the ELF header in executables and shared libraries can be bumped to indicate the minimum ABI requirement on the dynamic linker. However, EI_ABIVERSION in executables isn't checked by the Linux kernel ELF loader nor the existing dynamic linker. Executables will crash mysteriously if the dynamic linker doesn't support the ABI features required by the EI_ABIVERSION field. The dynamic linker should be changed to check EI_ABIVERSION in executables. Add a glibc version, GLIBC_ABI_DT_RELR, to indicate DT_RELR support so that the existing dynamic linkers will issue an error on executables with GLIBC_ABI_DT_RELR dependency. Issue an error if there is a DT_RELR entry without GLIBC_ABI_DT_RELR dependency nor GLIBC_PRIVATE definition. Support __placeholder_only_for_empty_version_map as the placeholder symbol used only for empty version map to generate GLIBC_ABI_DT_RELR without any symbols. --- elf/Makefile | 18 ++++++++++++++++-- elf/Versions | 5 +++++ elf/dl-version.c | 33 +++++++++++++++++++++++++++++++-- elf/libc-abi-version.exp | 1 + include/link.h | 6 ++++++ scripts/abilist.awk | 2 ++ scripts/versions.awk | 7 ++++++- 7 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 elf/libc-abi-version.exp diff --git a/elf/Makefile b/elf/Makefile index 71b08c75dd..a6515e8a21 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -48,6 +48,10 @@ routines = \ rtld_static_init \ # routines +ifeq ($(have-dt-relr),yes) +check-abi-version-libc = $(objpfx)check-abi-version-libc.out +endif + # The core dynamic linking functions are in libc for the static and # profiled libraries. dl-routines = \ @@ -1106,8 +1110,8 @@ $(eval $(call include_dsosort_tests,dso-sort-tests-1.def)) $(eval $(call include_dsosort_tests,dso-sort-tests-2.def)) endif -check-abi: $(objpfx)check-abi-ld.out -tests-special += $(objpfx)check-abi-ld.out +check-abi: $(objpfx)check-abi-ld.out $(check-abi-version-libc) +tests-special += $(objpfx)check-abi-ld.out $(check-abi-version-libc) update-abi: update-abi-ld update-all-abi: update-all-abi-ld @@ -2747,3 +2751,13 @@ $(objpfx)check-tst-relr-pie.out: $(objpfx)tst-relr-pie | sed -ne '/required from libc.so/,$$ p' \ | grep GLIBC_ABI_DT_RELR > $@; \ $(evaluate-test) + +$(objpfx)check-abi-version-libc.out: libc-abi-version.exp \ + $(objpfx)libc.symlist-abi-version + cmp $^ > $@; \ + $(evaluate-test) + +$(objpfx)libc.symlist-abi-version: $(common-objpfx)libc.so + LC_ALL=C $(NM) -D $< | grep " GLIBC_ABI_" \ + | sed "s/^0\+/00000000/" > $@T + mv -f $@T $@ diff --git a/elf/Versions b/elf/Versions index 8bed855d8c..a9ff278de7 100644 --- a/elf/Versions +++ b/elf/Versions @@ -23,6 +23,11 @@ libc { GLIBC_2.35 { _dl_find_object; } + GLIBC_ABI_DT_RELR { + # This symbol is used only for empty version map and will be removed + # by scripts/versions.awk. + __placeholder_only_for_empty_version_map; + } GLIBC_PRIVATE { # functions used in other libraries __libc_early_init; diff --git a/elf/dl-version.c b/elf/dl-version.c index b47bd91727..720ec596a5 100644 --- a/elf/dl-version.c +++ b/elf/dl-version.c @@ -214,12 +214,20 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) while (1) { /* Match the symbol. */ + const char *string = strtab + aux->vna_name; result |= match_symbol (DSO_FILENAME (map->l_name), map->l_ns, aux->vna_hash, - strtab + aux->vna_name, - needed->l_real, verbose, + string, needed->l_real, verbose, aux->vna_flags & VER_FLG_WEAK); + if (map->l_abi_version == lav_none + /* 0xfd0e42: _dl_elf_hash ("GLIBC_ABI_DT_RELR"). */ + && aux->vna_hash == 0xfd0e42 + && __glibc_likely (strcmp (string, + "GLIBC_ABI_DT_RELR") + == 0)) + map->l_abi_version = lav_dt_relr_ref; + /* Compare the version index. */ if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high) ndx_high = aux->vna_other & 0x7fff; @@ -253,6 +261,16 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr); while (1) { + /* 0x0963cf85: _dl_elf_hash ("GLIBC_PRIVATE"). */ + if (ent->vd_hash == 0x0963cf85) + { + ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) ent + + ent->vd_aux); + if (__glibc_likely (strcmp ("GLIBC_PRIVATE", + strtab + aux->vda_name) == 0)) + map->l_abi_version = lav_private_def; + } + if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high) ndx_high = ent->vd_ndx & 0x7fff; @@ -352,6 +370,17 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) } } + /* Issue an error if there is a DT_RELR entry without GLIBC_ABI_DT_RELR + dependency nor GLIBC_PRIVATE definition. */ + if (map->l_info[DT_RELR] != NULL + && __glibc_unlikely (map->l_abi_version == lav_none)) + { + _dl_exception_create + (&exception, DSO_FILENAME (map->l_name), + N_("DT_RELR without GLIBC_ABI_DT_RELR dependency")); + goto call_error; + } + return result; } diff --git a/elf/libc-abi-version.exp b/elf/libc-abi-version.exp new file mode 100644 index 0000000000..455088dc6b --- /dev/null +++ b/elf/libc-abi-version.exp @@ -0,0 +1 @@ +00000000 A GLIBC_ABI_DT_RELR diff --git a/include/link.h b/include/link.h index bef2820b40..ce9e3d5214 100644 --- a/include/link.h +++ b/include/link.h @@ -177,6 +177,12 @@ struct link_map lt_library, /* Library needed by main executable. */ lt_loaded /* Extra run-time loaded shared object. */ } l_type:2; + enum /* ABI dependency of this object. */ + { + lav_none, /* No ABI dependency. */ + lav_dt_relr_ref, /* Need GLIBC_ABI_DT_RELR. */ + lav_private_def /* Define GLIBC_PRIVATE. */ + } l_abi_version:2; unsigned int l_relocated:1; /* Nonzero if object's relocations done. */ unsigned int l_init_called:1; /* Nonzero if DT_INIT function called. */ unsigned int l_global:1; /* Nonzero if object in _dl_global_scope. */ diff --git a/scripts/abilist.awk b/scripts/abilist.awk index 24a34ccbed..6cc7af6ac8 100644 --- a/scripts/abilist.awk +++ b/scripts/abilist.awk @@ -55,6 +55,8 @@ $2 == "g" || $2 == "w" && (NF == 7 || NF == 8) { # caused STV_HIDDEN symbols to appear in .dynsym, though that is useless. if (NF > 7 && $7 == ".hidden") next; + if (version ~ /^GLIBC_ABI_/ && !include_abi_version) next; + if (version == "GLIBC_PRIVATE" && !include_private) next; desc = ""; diff --git a/scripts/versions.awk b/scripts/versions.awk index 357ad1355e..d70b07bd1a 100644 --- a/scripts/versions.awk +++ b/scripts/versions.awk @@ -185,8 +185,13 @@ END { closeversion(oldver, veryoldver); veryoldver = oldver; } - printf("%s {\n global:\n", $2) > outfile; oldver = $2; + # Skip the placeholder symbol used only for empty version map. + if ($3 == "__placeholder_only_for_empty_version_map;") { + printf("%s {\n", $2) > outfile; + continue; + } + printf("%s {\n global:\n", $2) > outfile; } printf(" ") > outfile; for (n = 3; n <= NF; ++n) { From patchwork Mon Feb 7 23:51:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 50899 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 78C7A385842B for ; Mon, 7 Feb 2022 23:55:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 78C7A385842B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1644278121; bh=CixCWbv8kWbGFbYU9ShnxAPljqdZPTfJSI3WTImhGZc=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Kil5tKTLJdkVv3zwumXkbj1SzpoXyG54aN6+fT0Zl0Y6Y6o4qxPJSqoh940PlW6j/ CF3BLkVOAuLmpi9KxXwyxruPxwBBorLMyq3iG43swo0WQOyhOBKa9zfDQoPowKT+Ii GJ+/M9cDsC3BNW8reAiarPUDIUw4yVOmXxkVq7Ns= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x42a.google.com (mail-pf1-x42a.google.com [IPv6:2607:f8b0:4864:20::42a]) by sourceware.org (Postfix) with ESMTPS id 6DF593858C3A for ; Mon, 7 Feb 2022 23:51:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6DF593858C3A Received: by mail-pf1-x42a.google.com with SMTP id y5so14860473pfe.4 for ; Mon, 07 Feb 2022 15:51:31 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CixCWbv8kWbGFbYU9ShnxAPljqdZPTfJSI3WTImhGZc=; b=B83Z24gZatiW4QxIRwr7a3R6Y5fDfc9wk4De1xXFH6HiwbeDjXOi3vXeyIt5GdEaMI XoxFY8VaS7beJTmU69zfwKzEs4aHvMVyekWbvd6Vtvm1uTUPrsx3lvUJRGVbLMZqvJYx gvEHV5XCLtZUgBYEhmiImYG9VMMKiR7AYCg7W4XeNxKYpT2CdgCPxSXeO/JFfEmsDuTG 0RitSB4RNtdNCWhIXUidM597nhXOY/8pmuxhxtfo3Z6qNX/4sPcLOCE9uBbuFwLevk7z rnSfQqMkDNljHhir1Pabg4BH8iHdPVyRxsq1BhZqpAo+HlmXfukV4Q7dYc/pk+S0lJ1s JmkQ== X-Gm-Message-State: AOAM532hRemfm5LR0poyxTivN2SELmm/kO+Drzi27G3hFKoSkcAx7+Zt Y5lHm5wyxQzQpHCaWZVVZ4I= X-Google-Smtp-Source: ABdhPJzM3HbILG1uzYYHnDft9WG1MtdGVV4Obbm72xmmggsGt9rT2qmL5zHDXtYEhvs7HsAmUHYOtQ== X-Received: by 2002:a63:491d:: with SMTP id w29mr1401747pga.366.1644277890271; Mon, 07 Feb 2022 15:51:30 -0800 (PST) Received: from gnu-tgl-2.localdomain ([172.58.38.240]) by smtp.gmail.com with ESMTPSA id c26sm9105322pgb.53.2022.02.07.15.51.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Feb 2022 15:51:28 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id B69433007E5; Mon, 7 Feb 2022 15:51:27 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v3 4/5] Add --disable-default-dt-relr Date: Mon, 7 Feb 2022 15:51:26 -0800 Message-Id: <20220207235127.1807294-5-hjl.tools@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207235127.1807294-1-hjl.tools@gmail.com> References: <20220207235127.1807294-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3029.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Joseph Myers Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Enable DT_RELR in glibc shared libraries and position independent executables (PIE) automatically if linker supports -z pack-relative-relocs. Also add a new configuration option, --disable-default-dt-relr, to avoid DT_RELR usage in glibc shared libraries and PIEs. Reviewed-by: Fangrui Song --- INSTALL | 6 ++++++ Makeconfig | 19 +++++++++++++++++++ Makerules | 2 ++ configure | 18 ++++++++++++++++++ configure.ac | 13 +++++++++++++ elf/Makefile | 4 +++- manual/install.texi | 5 +++++ 7 files changed, 66 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index 63c022d6b9..4a6506f11f 100644 --- a/INSTALL +++ b/INSTALL @@ -133,6 +133,12 @@ if 'CFLAGS' is specified it must enable optimization. For example: used with the GCC option, -static-pie, which is available with GCC 8 or above, to create static PIE. +'--disable-default-dt-relr' + Don't enable DT_RELR in glibc shared libraries and position + independent executables (PIE). By default, DT_RELR is enabled in + glibc shared libraries and position independent executables on + targets that support it. + '--enable-cet' '--enable-cet=permissive' Enable Intel Control-flow Enforcement Technology (CET) support. diff --git a/Makeconfig b/Makeconfig index 47db08d6ae..70c0acc065 100644 --- a/Makeconfig +++ b/Makeconfig @@ -358,6 +358,23 @@ else real-static-start-installed-name = $(static-start-installed-name) endif +# Linker option to enable and disable DT-RELR. +ifeq ($(have-dt-relr),yes) +dt-relr-ldflag = -Wl,-z,pack-relative-relocs +no-dt-relr-ldflag = -Wl,-z,nopack-relative-relocs +else +dt-relr-ldflag = +no-dt-relr-ldflag = +endif + +# Default linker option for DT-RELR. +ifeq (yes,$(build-dt-relr-default)) +default-rt-relr-ldflag = $(dt-relr-ldflag) +else +default-rt-relr-ldflag = $(no-dt-relr-ldflag) +endif +LDFLAGS-rtld += $(default-rt-relr-ldflag) + ifeq (yesyes,$(build-shared)$(have-z-combreloc)) combreloc-LDFLAGS = -Wl,-z,combreloc LDFLAGS.so += $(combreloc-LDFLAGS) @@ -419,6 +436,7 @@ link-extra-libs-tests = $(libsupport) # Command for linking PIE programs with the C library. ifndef +link-pie +link-pie-before-inputs = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \ + $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \ -Wl,-O1 -nostdlib -nostartfiles \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ @@ -451,6 +469,7 @@ endif ifndef +link-static +link-static-before-inputs = -nostdlib -nostartfiles -static \ $(if $($(@F)-no-pie),$(no-pie-ldflag),$(static-pie-ldflag)) \ + $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \ $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \ $(+preinit) $(+prectorT) diff --git a/Makerules b/Makerules index 5de2cec6be..260c7b7253 100644 --- a/Makerules +++ b/Makerules @@ -536,6 +536,7 @@ lib%.so: lib%_pic.a $(+preinit) $(+postinit) $(link-libc-deps) define build-shlib-helper $(LINK.o) -shared -static-libgcc -Wl,-O1 $(sysdep-LDFLAGS) \ $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) $(rtld-LDFLAGS) \ + $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \ $(extra-B-$(@F:lib%.so=%).so) -B$(csu-objpfx) \ $(extra-B-$(@F:lib%.so=%).so) $(load-map-file) \ -Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \ @@ -595,6 +596,7 @@ endef define build-module-helper $(LINK.o) -shared -static-libgcc $(sysdep-LDFLAGS) $(rtld-LDFLAGS) \ $(if $($(@F)-no-z-defs)$(no-z-defs),,-Wl,-z,defs) \ + $(if $($(@F)-no-dt-relr),$(no-dt-relr-ldflag),$(default-rt-relr-ldflag)) \ -B$(csu-objpfx) $(load-map-file) \ $(LDFLAGS.so) $(LDFLAGS-$(@F:%.so=%).so) \ $(link-test-modules-rpath-link) \ diff --git a/configure b/configure index 9156e29fe9..ee4137a977 100755 --- a/configure +++ b/configure @@ -768,6 +768,7 @@ enable_sanity_checks enable_shared enable_profile enable_default_pie +enable_default_dt_relr enable_timezone_tools enable_hardcoded_path_in_tests enable_hidden_plt @@ -1425,6 +1426,7 @@ Optional Features: --enable-profile build profiled library [default=no] --disable-default-pie Do not build glibc programs and the testsuite as PIE [default=no] + --disable-dt-relr Do not enable DT_RELR in glibc[default=no] --disable-timezone-tools do not install timezone tools [default=install] --enable-hardcoded-path-in-tests @@ -3441,6 +3443,13 @@ else default_pie=yes fi +# Check whether --enable-default-dt-relr was given. +if test "${enable_default_dt_relr+set}" = set; then : + enableval=$enable_default_dt_relr; default_dt_relr=$enableval +else + default_dt_relr=yes +fi + # Check whether --enable-timezone-tools was given. if test "${enable_timezone_tools+set}" = set; then : enableval=$enable_timezone_tools; enable_timezone_tools=$enableval @@ -7136,6 +7145,15 @@ fi config_vars="$config_vars enable-static-pie = $libc_cv_static_pie" +# Disable build-dt-relr-default if linker does not support it or glibc is +# configured with --disable-default-dt-relr. +build_dt_relr_default=$default_dt_relr +if test "x$build_dt_relr_default" != xno; then + build_dt_relr_default=$libc_cv_dt_relr +fi +config_vars="$config_vars +build-dt-relr-default = $build_dt_relr_default" + # Set the `multidir' variable by grabbing the variable from the compiler. # We do it once and save the result in a generated makefile. libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` diff --git a/configure.ac b/configure.ac index 5c09871fee..680b036ffa 100644 --- a/configure.ac +++ b/configure.ac @@ -197,6 +197,11 @@ AC_ARG_ENABLE([default-pie], [Do not build glibc programs and the testsuite as PIE @<:@default=no@:>@]), [default_pie=$enableval], [default_pie=yes]) +AC_ARG_ENABLE([default-dt-relr], + AS_HELP_STRING([--disable-dt-relr], + [Do not enable DT_RELR in glibc@<:@default=no@:>@]), + [default_dt_relr=$enableval], + [default_dt_relr=yes]) AC_ARG_ENABLE([timezone-tools], AS_HELP_STRING([--disable-timezone-tools], [do not install timezone tools @<:@default=install@:>@]), @@ -1914,6 +1919,14 @@ if test "$libc_cv_static_pie" = "yes"; then fi LIBC_CONFIG_VAR([enable-static-pie], [$libc_cv_static_pie]) +# Disable build-dt-relr-default if linker does not support it or glibc is +# configured with --disable-default-dt-relr. +build_dt_relr_default=$default_dt_relr +if test "x$build_dt_relr_default" != xno; then + build_dt_relr_default=$libc_cv_dt_relr +fi +LIBC_CONFIG_VAR([build-dt-relr-default], [$build_dt_relr_default]) + # Set the `multidir' variable by grabbing the variable from the compiler. # We do it once and save the result in a generated makefile. libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` diff --git a/elf/Makefile b/elf/Makefile index a6515e8a21..1727f5acc0 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -1570,6 +1570,7 @@ $(objpfx)nodlopen2.out: $(objpfx)nodlopenmod2.so $(objpfx)filtmod1.so: $(objpfx)filtmod1.os $(objpfx)filtmod2.so $(LINK.o) -shared -o $@ -B$(csu-objpfx) $(LDFLAGS.so) \ + $(default-rt-relr-ldflag) \ -L$(subst :, -L,$(rpath-link)) \ -Wl,-rpath-link=$(rpath-link) \ $< -Wl,-F,$(objpfx)filtmod2.so @@ -2376,7 +2377,7 @@ $(objpfx)tst-big-note: $(objpfx)tst-big-note-lib.so # artificial, large note in tst-big-note-lib.o and invalidate the # test. $(objpfx)tst-big-note-lib.so: $(objpfx)tst-big-note-lib.o - $(LINK.o) -shared -o $@ $(LDFLAGS.so) $< + $(LINK.o) -shared -o $@ $(LDFLAGS.so) $(default-rt-relr-ldflag) $< $(objpfx)tst-unwind-ctor: $(objpfx)tst-unwind-ctor-lib.so @@ -2682,6 +2683,7 @@ $(objpfx)tst-ro-dynamic: $(objpfx)tst-ro-dynamic-mod.so $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \ tst-ro-dynamic-mod.map $(LINK.o) -nostdlib -nostartfiles -shared -o $@ \ + $(default-rt-relr-ldflag) \ -Wl,--script=tst-ro-dynamic-mod.map \ $(objpfx)tst-ro-dynamic-mod.os diff --git a/manual/install.texi b/manual/install.texi index 29c52f2927..04ea996561 100644 --- a/manual/install.texi +++ b/manual/install.texi @@ -161,6 +161,11 @@ and architecture support it, static executables are built as static PIE and the resulting glibc can be used with the GCC option, -static-pie, which is available with GCC 8 or above, to create static PIE. +@item --disable-default-dt-relr +Don't enable DT_RELR in glibc shared libraries and position independent +executables (PIE). By default, DT_RELR is enabled in glibc shared +libraries and position independent executables on targets that support it. + @item --enable-cet @itemx --enable-cet=permissive Enable Intel Control-flow Enforcement Technology (CET) support. When From patchwork Mon Feb 7 23:51:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 50896 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 52B333858422 for ; Mon, 7 Feb 2022 23:53:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 52B333858422 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1644277995; bh=4DjsrgG0n0rH6zpK03mogUU7x5GWmMq7rT0Qtz0GGqc=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=eMBlTs4no8dhEKyanjouiMuhCNjqYbPIyaPrgItqAGRqf/TTlssr1IB8edsdA27bV uPQwELYry4EGznGWyi+tmCnz5NQV7ad60AmZdSPVKMrVLUSeEctojOvK1cVHjAO3jx 7QEKKajbZHt2ILEOGBMFVImKuQ6lkurTwPNLW7OM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by sourceware.org (Postfix) with ESMTPS id 1D58A385840D for ; Mon, 7 Feb 2022 23:51:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1D58A385840D Received: by mail-pl1-x62d.google.com with SMTP id t9so10186232plg.13 for ; Mon, 07 Feb 2022 15:51:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4DjsrgG0n0rH6zpK03mogUU7x5GWmMq7rT0Qtz0GGqc=; b=Y74J54RlJmWeX9cR60LSnV77CPNDzwX5kRdgrSaQXxrFAh+KCzb50oJHVSJEuIOmb3 tQ4QnDbvxTRGI9WaLbq4C40RlH//XthQBpN3VkaLCgYWuCOAd5EfeW7BzfUbX/syQw44 WEGtkGU41j9qoKnArfWw15sT+RWKM6kFtUJ8k4Rhl0WCFh1RYk5SwaULGwuGiqGRQ/e4 ChTP9bh9HgGigYbocFiB1MvEHCj+6dIGs3tgWtnmtHI4qEdR7uzFZlowN22kWrY0Niw5 pWi5t63JB5o+pOZlCZxntYpaZD4dqMzCE3wBaKJMhzoO7dwVJ9AOIGzxpYsyNuhkD8b4 vlkg== X-Gm-Message-State: AOAM532V2XSqh0g1RhtGczH4fE8O81MdzhNyFNKAen+RsUQ5uPJFJtPK AQ5Mj65WMQ2vsAYUtAjwtsk= X-Google-Smtp-Source: ABdhPJxZ2tCZarZK3SE8/7IF+oS+FxILtueTtxNt/HGagBAptx/KDBeUOv7CIMRr3Ca9MOf7hSHsyw== X-Received: by 2002:a17:90b:707:: with SMTP id s7mr1427787pjz.99.1644277891211; Mon, 07 Feb 2022 15:51:31 -0800 (PST) Received: from gnu-tgl-2.localdomain ([172.58.38.240]) by smtp.gmail.com with ESMTPSA id u12sm13854473pfk.220.2022.02.07.15.51.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Feb 2022 15:51:30 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id C28BA3007E6; Mon, 7 Feb 2022 15:51:27 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v3 5/5] NEWS: Mention DT_RELR support Date: Mon, 7 Feb 2022 15:51:27 -0800 Message-Id: <20220207235127.1807294-6-hjl.tools@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207235127.1807294-1-hjl.tools@gmail.com> References: <20220207235127.1807294-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3029.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Joseph Myers Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7b8febcb72..aadf15e804 100644 --- a/NEWS +++ b/NEWS @@ -9,7 +9,7 @@ Version 2.36 Major new features: - [Add new features here] +* Support DT_RELR relative relocation format. Deprecated and removed features, and other changes affecting compatibility: