From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H2 autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 14887 invoked from network); 1 Dec 2022 00:09:58 -0000 Received: from second.openwall.net (193.110.157.125) by inbox.vuxu.org with ESMTPUTF8; 1 Dec 2022 00:09:58 -0000 Received: (qmail 26165 invoked by uid 550); 1 Dec 2022 00:09:54 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 26130 invoked from network); 1 Dec 2022 00:09:54 -0000 Date: Wed, 30 Nov 2022 19:09:42 -0500 From: Rich Felker To: "A. Wilcox" Cc: musl@lists.openwall.com Message-ID: <20221201000941.GS29905@brightrain.aerifal.cx> References: <20221128194740.GA23755@voyager> <20221130151234.GR29905@brightrain.aerifal.cx> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="9a9Vq1BJdYBEXpLG" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] Invalid page size reference in __dls2 --9a9Vq1BJdYBEXpLG Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On Wed, Nov 30, 2022 at 05:28:38PM -0600, A. Wilcox wrote: > > On Nov 30, 2022, at 9:12 AM, Rich Felker wrote: > > > > Nice catch. The references to libc are not valid in __dls2. If they > > were, I would just re-run kernel_mapped_dso() from __dls2b or > > something to get the right relro map, but I think instead we should do > > something like the attached. > > > > Rich > > > > LGTM but needs a # before the ‘define’. > > This explains a weird error I was seeing with gcompat on aarch64. Does this look better (message included)? --9a9Vq1BJdYBEXpLG Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001-ldso-fix-invalid-early-references-to-extern-linkage-.patch" >From f47a8cdd250d9163fcfb39bf4e9d813957c0b187 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Wed, 30 Nov 2022 18:59:08 -0500 Subject: [PATCH] ldso: fix invalid early references to extern-linkage libc.page_size when PAGE_SIZE is not constant, internal/libc.h defines it to expand to libc.page_size. however, kernel_mapped_dso, reachable from stage 2 of the dynamic linker bootstrap (__dls2), needs PAGE_SIZE to interpret the relro range. at this point the libc object is both uninitialized and invalid to access according to our model for bootstrapping, which does not assume any external-linkage objects are accessible until stages 2b/3. in practice it likely worked because hidden visibility tends to behave like internal linkage, but this is not a property that the dynamic linker was designed to rely upon. this bug likely manifested as relro malfunction on archs with variable page size, due to incorrect mask when aligning the relro bounds to page boundaries. while there are certainly more direct ways to fix the known problem point here, a maximally future-proof way is to just bypass the libc.h PAGE_SIZE definition in the dynamic linker and instead have dynlink.c define its own internal-linkage object for variable page size. then, if anything else in stage 2 ever ends up referencing PAGE_SIZE, it will just automatically work right. --- ldso/dynlink.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 8068fb37..09f3b0a8 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -21,9 +21,15 @@ #include #include "pthread_impl.h" #include "fork_impl.h" -#include "libc.h" #include "dynlink.h" +static size_t ldso_page_size; +#ifndef PAGE_SIZE +#define PAGE_SIZE ldso_page_size +#endif + +#include "libc.h" + #define malloc __libc_malloc #define calloc __libc_calloc #define realloc __libc_realloc @@ -1723,6 +1729,7 @@ hidden void __dls2(unsigned char *base, size_t *sp) ldso.phnum = ehdr->e_phnum; ldso.phdr = laddr(&ldso, ehdr->e_phoff); ldso.phentsize = ehdr->e_phentsize; + search_vec(auxv, &ldso_page_size, AT_PAGESZ); kernel_mapped_dso(&ldso); decode_dyn(&ldso); -- 2.21.0 --9a9Vq1BJdYBEXpLG--