From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg1-x52e.google.com (mail-pg1-x52e.google.com [IPv6:2607:f8b0:4864:20::52e]) by sourceware.org (Postfix) with ESMTPS id 0E7993858C83 for ; Fri, 22 Apr 2022 22:37:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0E7993858C83 Received: by mail-pg1-x52e.google.com with SMTP id 15so64968pgf.4 for ; Fri, 22 Apr 2022 15:37:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=1tbKOs3yVfR8yAfv1UEY8JU30kI93/4fDLt1RXYIa94=; b=YWt9EwjIMCntgikfN7wDZKN/5AZm7KUSio/5xvlESVd0FzKSHS2tP+V0pOF8wVNHwX QPa5z5xfOWoYTYgvwT1ovtjiyoVUIBmsLykC2m2Vfb18HTzBOhJHsAvBi7igMM25aEvY su+x9ymOudPO/tueiFaiUk+BzCHcJ4upgDvaOBL5UTj1VF9YVefwNBa27WSln1bGsaW0 JL+VjHnfciwBO5HGT2uLh5LLMUjvLTrafdofqNZNJaymYlhdTWAWMOlDIBp5roVmWrUZ 81JmdXskKWbV7poURaScyFYjxniHa+T3JBY0EOxIvmJu/1AzJQErTOY4zmoK5kljl+Hu er1A== X-Gm-Message-State: AOAM532Km6RWFNFU++GD8Wg1eJQouSw0kKdQsWEeYqaKfhQ+VLll3Lwp G1OKpkNBWpB5GLeAgWev98y8Ng2oMSwA1Q== X-Google-Smtp-Source: ABdhPJxgX763cS1ihpVgoyoxw3yafWJwhTtB6nfadMqAtlsMGe+u6socZqvkp9bEzlq/jEHdZhQyKA== X-Received: by 2002:a63:7cf:0:b0:399:58f3:9acc with SMTP id 198-20020a6307cf000000b0039958f39accmr5783956pgh.149.1650667067659; Fri, 22 Apr 2022 15:37:47 -0700 (PDT) Received: from google.com ([2620:15c:2ce:200:8f89:e96b:b8b8:a84f]) by smtp.gmail.com with ESMTPSA id y3-20020a056a00190300b004fa2411bb92sm3953209pfi.93.2022.04.22.15.37.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 22 Apr 2022 15:37:47 -0700 (PDT) Date: Fri, 22 Apr 2022 15:37:43 -0700 From: Fangrui Song To: "H.J. Lu" Cc: libc-alpha@sourceware.org, Adhemerval Zanella Subject: Re: [PATCH v11 2/7] Add GLIBC_ABI_DT_RELR for DT_RELR support Message-ID: <20220422223743.q4tyo3cuddyf6hl2@google.com> References: <20220422190139.2615492-1-hjl.tools@gmail.com> <20220422190139.2615492-3-hjl.tools@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: <20220422190139.2615492-3-hjl.tools@gmail.com> X-Spam-Status: No, score=-26.5 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK, USER_IN_DEF_DKIM_WL, USER_IN_DEF_SPF_WL 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-List-Received-Date: Fri, 22 Apr 2022 22:38:01 -0000 On 2022-04-22, H.J. Lu wrote: >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. When there is a DT_VERNEED entry with >libc.so on DT_NEEDED, issue an error if there is a DT_RELR entry without >GLIBC_ABI_DT_RELR dependency. > >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 | 14 ++++++++++++-- > elf/Versions | 5 +++++ > elf/dl-version.c | 35 +++++++++++++++++++++++++++++++++-- > include/link.h | 2 ++ > scripts/abilist.awk | 2 ++ > scripts/versions.awk | 7 ++++++- > 6 files changed, 60 insertions(+), 5 deletions(-) > >diff --git a/elf/Makefile b/elf/Makefile >index 8ed6c3b0b1..f288f866f2 100644 >--- a/elf/Makefile >+++ b/elf/Makefile >@@ -1143,8 +1143,12 @@ $(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 \ >+ $(objpfx)check-abi-version-libc.out >+tests-special += \ >+ $(objpfx)check-abi-ld.out \ >+ $(objpfx)check-abi-version-libc.out \ >+# tests-special > update-abi: update-abi-ld > update-all-abi: update-all-abi-ld > >@@ -2773,3 +2777,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-abi-version-libc.out: $(common-objpfx)libc.so >+ LC_ALL=C $(READELF) -V -W $< \ >+ | sed -ne '/.gnu.version_d/, /.gnu.version_r/ p' \ >+ | grep GLIBC_ABI_DT_RELR > $@; \ >+ $(evaluate-test) >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..cda0889209 100644 >--- a/elf/dl-version.c >+++ b/elf/dl-version.c >@@ -214,12 +214,19 @@ _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); > >+ /* 0xfd0e42: _dl_elf_hash ("GLIBC_ABI_DT_RELR"). */ >+ if (aux->vna_hash == 0xfd0e42 >+ && __glibc_likely (strcmp (string, >+ "GLIBC_ABI_DT_RELR") >+ == 0)) >+ map->l_dt_relr_ref = 1; >+ > /* Compare the version index. */ > if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high) > ndx_high = aux->vna_other & 0x7fff; >@@ -352,6 +359,30 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) > } > } > >+ /* When there is a DT_VERNEED entry with libc.so on DT_NEEDED, issue >+ an error if there is a DT_RELR entry without GLIBC_ABI_DT_RELR >+ dependency. */ >+ if (dyn != NULL >+ && map->l_info[DT_NEEDED] != NULL >+ && map->l_info[DT_RELR] != NULL >+ && __glibc_unlikely (!map->l_dt_relr_ref)) >+ { >+ const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); >+ const ElfW(Dyn) *d; >+ for (d = map->l_ld; d->d_tag != DT_NULL; ++d) >+ if (d->d_tag == DT_NEEDED) >+ { >+ const char *name = strtab + d->d_un.d_val; >+ if (strncmp (name, "libc.so.", 8) == 0) >+ { >+ _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/include/link.h b/include/link.h >index 03db14c7b0..0ac82d7c77 100644 >--- a/include/link.h >+++ b/include/link.h >@@ -177,6 +177,8 @@ struct link_map > lt_library, /* Library needed by main executable. */ > lt_loaded /* Extra run-time loaded shared object. */ > } l_type:2; >+ unsigned int l_dt_relr_ref:1; /* Nonzero if GLIBC_ABI_DT_RELR is >+ referenced. */ > 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) { >-- >2.35.1 Still LG Reviewed-by: Fangrui Song