From patchwork Fri Mar 17 06:32:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758082 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=GzjBDDsU; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDpD5x2gz247R for ; Fri, 17 Mar 2023 17:32:52 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AD84E3853567 for ; Fri, 17 Mar 2023 06:32:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AD84E3853567 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034770; bh=BkpUl4IjziF+k30QNWuSr+3VSIfaClg+Fa7lsLsF5TU=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=GzjBDDsU1S9uCRV/fdYiSo2YRRGAYX5JjWzie2JuXYAwGLMrxp+60jpZUQZTWlt4+ TtW3FOWkEBqLdGAPQqbT31tI0dNd+j4YCN5ajqa2gWwDTS6ZQRFQKWeE1tktj4Q5CW KYwtgmMEyOy0m4+VIL2fR3B2PmK83DgapWZR8LLI= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward104p.mail.yandex.net (forward104p.mail.yandex.net [77.88.28.107]) by sourceware.org (Postfix) with ESMTPS id A11E93858431 for ; Fri, 17 Mar 2023 06:32:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A11E93858431 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward104p.mail.yandex.net (Yandex) with ESMTP id 1A2A13C21152 for ; Fri, 17 Mar 2023 09:32:29 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-L8lzXdDh; Fri, 17 Mar 2023 09:32:28 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 01/11] elf: strdup() l_name if no realname [BZ #30100] Date: Fri, 17 Mar 2023 11:32:00 +0500 Message-Id: <20230317063210.4118076-2-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" _dl_close_worker() has this code: /* This name always is allocated. */ free (imap->l_name); But in that particular case, while indeed being allocated, l_name doesn't point to the start of an allocation: new = (struct link_map *) calloc (sizeof (*new) + audit_space + sizeof (struct link_map *) + sizeof (*newname) + libname_len, 1); ... new->l_symbolic_searchlist.r_list = (struct link_map **) ((char *) (new + 1) + audit_space); new->l_libname = newname = (struct libname_list *) (new->l_symbolic_searchlist.r_list + 1); newname->name = (char *) memcpy (newname + 1, libname, libname_len); ... new->l_name = (char *) newname->name + libname_len - 1; It therefore cannot be freed separately. Use strdup("") as a simple fix. Signed-off-by: Stas Sergeev --- elf/dl-object.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/elf/dl-object.c b/elf/dl-object.c index f1f2ec956c..ab926cd4bf 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -122,7 +122,10 @@ _dl_new_object (char *realname, const char *libname, int type, #endif new->l_name = realname; else - new->l_name = (char *) newname->name + libname_len - 1; + /* When realname="", it is not allocated and points to the constant + string. Constness is dropped by an explicit cast. :( + So strdup() it here. */ + new->l_name = __strdup (""); new->l_type = type; /* If we set the bit now since we know it is never used we avoid From patchwork Fri Mar 17 06:32:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758086 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=WRQxXVFS; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDqT4CHPz2473 for ; Fri, 17 Mar 2023 17:33:57 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6F2AD3850216 for ; Fri, 17 Mar 2023 06:33:55 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6F2AD3850216 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034835; bh=gxt3dLBFfFy3wM6hT+ncEgS1kVZ3VQrzNdJHEf1ivsw=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=WRQxXVFSItG0QFt5ZASULnj3ap8ve0cECtcHDbJYmuqmG+2tgp63dHK8Q3ocnwA8Y k/m/q9O9wePPSGb6WWJndbLO4l+g1CNtc//vqCCnLFUElrzTKijhk+Pqj5BQxQNaKQ SM5YHRSwodfCPRTBM0CSVVvt3xUMxW0YzRaj3vUE= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102o.mail.yandex.net (forward102o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::602]) by sourceware.org (Postfix) with ESMTPS id 0BE133851C04 for ; Fri, 17 Mar 2023 06:33:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0BE133851C04 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward102o.mail.yandex.net (Yandex) with ESMTP id 0053F6FFB628 for ; Fri, 17 Mar 2023 09:32:30 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-DIcu3kAH; Fri, 17 Mar 2023 09:32:29 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 02/11] elf: switch _dl_map_segment() to anonymous mapping Date: Fri, 17 Mar 2023 11:32:01 +0500 Message-Id: <20230317063210.4118076-3-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" _dl_map_segment() was mapping entire file image and then was skipping the load of the first segment. Switch _dl_map_segment() to anonymous mapping and do not skip the map of the first segment. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-map-segments.h | 74 +++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index 504cfc0a41..075a1d1f4c 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -22,18 +22,26 @@ /* Map a segment and align it properly. */ static __always_inline ElfW(Addr) -_dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, - const size_t maplength, int fd) +_dl_map_segment (ElfW(Addr) mappref, size_t maplength, size_t mapalign, + unsigned prot) { - if (__glibc_likely (c->mapalign <= GLRO(dl_pagesize))) - return (ElfW(Addr)) __mmap ((void *) mappref, maplength, c->prot, - MAP_COPY|MAP_FILE, fd, c->mapoff); + int err; + unsigned map_flags = MAP_ANONYMOUS | MAP_PRIVATE; + +#ifdef MAP_DENYWRITE + /* Tell mmap() that we are mapping solib. This flag enables things + like LD_PREFER_MAP_32BIT_EXEC. */ + map_flags |= MAP_DENYWRITE; +#endif + if (__glibc_likely (mapalign <= GLRO(dl_pagesize))) + return (ElfW(Addr)) __mmap ((void *) mappref, maplength, prot, + map_flags, -1, 0); /* If the segment alignment > the page size, allocate enough space to ensure that the segment can be properly aligned. */ - ElfW(Addr) maplen = (maplength >= c->mapalign - ? (maplength + c->mapalign) - : (2 * c->mapalign)); + ElfW(Addr) maplen = (maplength >= mapalign + ? (maplength + mapalign) + : (2 * mapalign)); ElfW(Addr) map_start = (ElfW(Addr)) __mmap ((void *) mappref, maplen, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, @@ -41,26 +49,24 @@ _dl_map_segment (const struct loadcmd *c, ElfW(Addr) mappref, if (__glibc_unlikely ((void *) map_start == MAP_FAILED)) return map_start; - ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, c->mapalign); - map_start_aligned = (ElfW(Addr)) __mmap ((void *) map_start_aligned, - maplength, c->prot, - MAP_COPY|MAP_FILE|MAP_FIXED, - fd, c->mapoff); - if (__glibc_unlikely ((void *) map_start_aligned == MAP_FAILED)) - __munmap ((void *) map_start, maplen); - else + ElfW(Addr) map_start_aligned = ALIGN_UP (map_start, mapalign); + err = __mprotect ((void *) map_start_aligned, maplength, prot); + if (__glibc_unlikely (err)) { - /* Unmap the unused regions. */ - ElfW(Addr) delta = map_start_aligned - map_start; - if (delta) - __munmap ((void *) map_start, delta); - ElfW(Addr) map_end = map_start_aligned + maplength; - map_end = ALIGN_UP (map_end, GLRO(dl_pagesize)); - delta = map_start + maplen - map_end; - if (delta) - __munmap ((void *) map_end, delta); + __munmap ((void *) map_start, maplen); + return (ElfW(Addr)) MAP_FAILED; } + /* Unmap the unused regions. */ + ElfW(Addr) delta = map_start_aligned - map_start; + if (delta) + __munmap ((void *) map_start, delta); + ElfW(Addr) map_end = map_start_aligned + maplength; + map_end = ALIGN_UP (map_end, GLRO(dl_pagesize)); + delta = map_start + maplen - map_end; + if (delta) + __munmap ((void *) map_end, delta); + return map_start_aligned; } @@ -98,7 +104,8 @@ _dl_map_segments (struct link_map *l, int fd, - MAP_BASE_ADDR (l)); /* Remember which part of the address space this object uses. */ - l->l_map_start = _dl_map_segment (c, mappref, maplength, fd); + l->l_map_start = _dl_map_segment (mappref, maplength, c->mapalign, + c->prot); if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; @@ -123,14 +130,14 @@ _dl_map_segments (struct link_map *l, int fd, } l->l_contiguous = 1; - - goto postmap; } - - /* Remember which part of the address space this object uses. */ - l->l_map_start = c->mapstart + l->l_addr; - l->l_map_end = l->l_map_start + maplength; - l->l_contiguous = !has_holes; + else + { + /* Remember which part of the address space this object uses. */ + l->l_map_start = c->mapstart + l->l_addr; + l->l_map_end = l->l_map_start + maplength; + l->l_contiguous = !has_holes; + } while (c < &loadcmds[nloadcmds]) { @@ -143,7 +150,6 @@ _dl_map_segments (struct link_map *l, int fd, == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; - postmap: _dl_postprocess_loadcmd (l, header, c); if (c->allocend > c->dataend) From patchwork Fri Mar 17 06:32:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758083 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=ToDJxpCd; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDpK42Kjz2473 for ; Fri, 17 Mar 2023 17:32:57 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 090AF385086E for ; Fri, 17 Mar 2023 06:32:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 090AF385086E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034772; bh=yR1GAZF89e7Qg2UdhUf8n6NIlmuiTcxb4l8n6B4HsTc=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=ToDJxpCdPcoxcRMXUn191ansrv2ytInHoI/UIQKRxBswRbhfL2dawHyP+vyyctPI6 nYHIYZHmFZnO1tgexIuB5gl2iPXfv6eM2djZ9OuXus5BNcoU73MrYQRXABvBWOBq5t zHug8o3tXM1YfQRYm+XYm0KTF2TJsaeVNp1wYxlo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward104p.mail.yandex.net (forward104p.mail.yandex.net [77.88.28.107]) by sourceware.org (Postfix) with ESMTPS id CC4913858438 for ; Fri, 17 Mar 2023 06:32:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CC4913858438 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward104p.mail.yandex.net (Yandex) with ESMTP id C17313C2123C for ; Fri, 17 Mar 2023 09:32:30 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-BH63QUxH; Fri, 17 Mar 2023 09:32:30 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 03/11] elf: dont pass fd to _dl_process_pt_xx Date: Fri, 17 Mar 2023 11:32:02 +0500 Message-Id: <20230317063210.4118076-4-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" It is not used in these functions. rtld.c:rtld_setup_main_map() does the same. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index fcb39a78d4..ab8b648687 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1379,10 +1379,10 @@ cannot enable executable stack as shared object requires"); switch (ph[-1].p_type) { case PT_NOTE: - _dl_process_pt_note (l, fd, &ph[-1]); + _dl_process_pt_note (l, -1, &ph[-1]); break; case PT_GNU_PROPERTY: - _dl_process_pt_gnu_property (l, fd, &ph[-1]); + _dl_process_pt_gnu_property (l, -1, &ph[-1]); break; } From patchwork Fri Mar 17 06:32:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758085 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=Y1czH9bb; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDq340pvz2473 for ; Fri, 17 Mar 2023 17:33:35 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 88EEC38515C3 for ; Fri, 17 Mar 2023 06:33:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 88EEC38515C3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034813; bh=XP8jvDrU4S+V0dtOEmKrS6RvWcUR/9gZ4mka1EcOc/I=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Y1czH9bbbP33FlOIio5AFjx7ksQWZnGhTg4GHZBUGiNFqewRtp5x6QJTh8SuosckH 99+zUUwrcy7PzcggwNr21O8CB6ulh0Onr9oIX5KyHihJOqA+lN0LEx9+7Tp1DzxKez wiN3zFtzqN6oJb/S7DL6pr3aAIgU1oGnfsl4fQ14= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward205c.mail.yandex.net (forward205c.mail.yandex.net [IPv6:2a02:6b8:c03:500:1:45:d181:d205]) by sourceware.org (Postfix) with ESMTPS id 5453B3857803 for ; Fri, 17 Mar 2023 06:32:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5453B3857803 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward205c.mail.yandex.net (Yandex) with ESMTP id C93E841C76 for ; Fri, 17 Mar 2023 09:32:31 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-PUkcEXQG; Fri, 17 Mar 2023 09:32:31 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 04/11] elf: split _dl_map_object_from_fd() into reusable parts Date: Fri, 17 Mar 2023 11:32:03 +0500 Message-Id: <20230317063210.4118076-5-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.8 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" This is mostly a mechanical split, with just a very minor moves of 2 small code fragments. This change should introduce no functional differences. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 317 ++++++++++++++++++++++++++++---------------------- 1 file changed, 175 insertions(+), 142 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index ab8b648687..9e0e63b9a3 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -929,147 +929,25 @@ _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph) } } - -/* Map in the shared object NAME, actually located in REALNAME, and already - opened on FD. */ - -#ifndef EXTERNAL_MAP_FROM_FD -static -#endif -struct link_map * -_dl_map_object_from_fd (const char *name, const char *origname, int fd, - struct filebuf *fbp, char *realname, - struct link_map *loader, int l_type, int mode, - void **stack_endp, Lmid_t nsid) +static int +_ld_map_object_1 (struct link_map *l, int fd, + struct filebuf *fbp, + int mode, struct link_map *loader, + void **stack_endp, int *errval_p, + const char **errstring_p) { - struct link_map *l = NULL; const ElfW(Ehdr) *header; const ElfW(Phdr) *phdr; const ElfW(Phdr) *ph; size_t maplength; int type; /* Initialize to keep the compiler happy. */ - const char *errstring = NULL; - int errval = 0; - struct r_debug *r = _dl_debug_update (nsid); - bool make_consistent = false; - - /* Get file information. To match the kernel behavior, do not fill - in this information for the executable in case of an explicit - loader invocation. */ - struct r_file_id id; - if (mode & __RTLD_OPENEXEC) - { - assert (nsid == LM_ID_BASE); - memset (&id, 0, sizeof (id)); - } - else - { - if (__glibc_unlikely (!_dl_get_file_id (fd, &id))) - { - errstring = N_("cannot stat shared object"); - lose_errno: - errval = errno; - lose: - /* The file might already be closed. */ - if (fd != -1) - __close_nocancel (fd); - if (l != NULL && l->l_map_start != 0) - _dl_unmap_segments (l); - if (l != NULL && l->l_origin != (char *) -1l) - free ((char *) l->l_origin); - if (l != NULL && !l->l_libname->dont_free) - free (l->l_libname); - if (l != NULL && l->l_phdr_allocated) - free ((void *) l->l_phdr); - free (l); - free (realname); - - if (make_consistent && r != NULL) - { - r->r_state = RT_CONSISTENT; - _dl_debug_state (); - LIBC_PROBE (map_failed, 2, nsid, r); - } - - _dl_signal_error (errval, name, NULL, errstring); - } - - /* Look again to see if the real name matched another already loaded. */ - for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) - if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id)) - { - /* The object is already loaded. - Just bump its reference count and return it. */ - __close_nocancel (fd); - - /* If the name is not in the list of names for this object add - it. */ - free (realname); - add_name_to_object (l, name); - - return l; - } - } - -#ifdef SHARED - /* When loading into a namespace other than the base one we must - avoid loading ld.so since there can only be one copy. Ever. */ - if (__glibc_unlikely (nsid != LM_ID_BASE) - && (_dl_file_id_match_p (&id, &GL(dl_rtld_map).l_file_id) - || _dl_name_match_p (name, &GL(dl_rtld_map)))) - { - /* This is indeed ld.so. Create a new link_map which refers to - the real one for almost everything. */ - l = _dl_new_object (realname, name, l_type, loader, mode, nsid); - if (l == NULL) - goto fail_new; - - /* Refer to the real descriptor. */ - l->l_real = &GL(dl_rtld_map); - - /* Copy l_addr and l_ld to avoid a GDB warning with dlmopen(). */ - l->l_addr = l->l_real->l_addr; - l->l_ld = l->l_real->l_ld; - - /* No need to bump the refcount of the real object, ld.so will - never be unloaded. */ - __close_nocancel (fd); - - /* Add the map for the mirrored object to the object list. */ - _dl_add_to_namespace_list (l, nsid); - - return l; - } -#endif - - if (mode & RTLD_NOLOAD) - { - /* We are not supposed to load the object unless it is already - loaded. So return now. */ - free (realname); - __close_nocancel (fd); - return NULL; - } - - /* Print debugging message. */ - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) - _dl_debug_printf ("file=%s [%lu]; generating link map\n", name, nsid); +#define errstring (*errstring_p) +#define errval (*errval_p) /* This is the ELF header. We read it in `open_verify'. */ header = (void *) fbp->buf; - /* Enter the new object in the list of loaded objects. */ - l = _dl_new_object (realname, name, l_type, loader, mode, nsid); - if (__glibc_unlikely (l == NULL)) - { -#ifdef SHARED - fail_new: -#endif - errstring = N_("cannot create shared object descriptor"); - goto lose_errno; - } - /* Extract the remaining details we need from the ELF header and then read in the program header table. */ l->l_entry = header->e_entry; @@ -1093,7 +971,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, /* On most platforms presume that PT_GNU_STACK is absent and the stack is * executable. Other platforms default to a nonexecutable stack and don't * need PT_GNU_STACK to do so. */ - unsigned int stack_flags = DEFAULT_STACK_PERMS; + unsigned int stack_flags = DEFAULT_STACK_PERMS; { /* Scan the program header table, collecting its load commands. */ @@ -1386,15 +1264,6 @@ cannot enable executable stack as shared object requires"); break; } - /* We are done mapping in the file. We no longer need the descriptor. */ - if (__glibc_unlikely (__close_nocancel (fd) != 0)) - { - errstring = N_("cannot close file descriptor"); - goto lose_errno; - } - /* Signal that we closed the file. */ - fd = -1; - /* Failures before this point are handled locally via lose. There are no more failures in this function until return, to change that the cleanup handling needs to be updated. */ @@ -1419,6 +1288,23 @@ cannot enable executable stack as shared object requires"); (unsigned long int) l->l_phdr, (int) sizeof (void *) * 2, l->l_phnum); + return 0; + +lose_errno: + errval = errno; +lose: + return -1; + +#undef errval +#undef errstring +} + +static void +_ld_map_object_2 (struct link_map *l, int mode, + struct r_file_id id, const char *origname, + Lmid_t nsid, struct r_debug *r, + bool *make_consistent_p) +{ /* Set up the symbol hash table. */ _dl_setup_hash (l); @@ -1510,7 +1396,7 @@ cannot enable executable stack as shared object requires"); r->r_state = RT_ADD; _dl_debug_state (); LIBC_PROBE (map_start, 2, nsid, r); - make_consistent = true; + *make_consistent_p = true; } else assert (r->r_state == RT_ADD); @@ -1520,10 +1406,157 @@ cannot enable executable stack as shared object requires"); if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing) _dl_audit_objopen (l, nsid); #endif +} + +/* Map in the shared object NAME, actually located in REALNAME, and already + opened on FD. */ + +#ifndef EXTERNAL_MAP_FROM_FD +static +#endif +struct link_map * +_dl_map_object_from_fd (const char *name, const char *origname, int fd, + struct filebuf *fbp, char *realname, + struct link_map *loader, int l_type, int mode, + void **stack_endp, Lmid_t nsid) +{ + struct link_map *l = NULL; + /* Initialize to keep the compiler happy. */ + const char *errstring = NULL; + int errval = 0; + struct r_debug *r = _dl_debug_update (nsid); + bool make_consistent = false; + + /* Get file information. To match the kernel behavior, do not fill + in this information for the executable in case of an explicit + loader invocation. */ + struct r_file_id id; + if (mode & __RTLD_OPENEXEC) + { + assert (nsid == LM_ID_BASE); + memset (&id, 0, sizeof (id)); + } + else + { + if (__glibc_unlikely (!_dl_get_file_id (fd, &id))) + { + errstring = N_("cannot stat shared object"); + lose_errno: + errval = errno; + lose: + /* The file might already be closed. */ + if (fd != -1) + __close_nocancel (fd); + if (l != NULL && l->l_map_start != 0) + _dl_unmap_segments (l); + if (l != NULL && l->l_origin != (char *) -1l) + free ((char *) l->l_origin); + if (l != NULL && !l->l_libname->dont_free) + free (l->l_libname); + if (l != NULL && l->l_phdr_allocated) + free ((void *) l->l_phdr); + free (l); + free (realname); + + if (make_consistent && r != NULL) + { + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + LIBC_PROBE (map_failed, 2, nsid, r); + } + + _dl_signal_error (errval, name, NULL, errstring); + } + + /* Look again to see if the real name matched another already loaded. */ + for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) + if (!l->l_removed && _dl_file_id_match_p (&l->l_file_id, &id)) + { + /* The object is already loaded. + Just bump its reference count and return it. */ + __close_nocancel (fd); + + /* If the name is not in the list of names for this object add + it. */ + free (realname); + add_name_to_object (l, name); + + return l; + } + } + +#ifdef SHARED + /* When loading into a namespace other than the base one we must + avoid loading ld.so since there can only be one copy. Ever. */ + if (__glibc_unlikely (nsid != LM_ID_BASE) + && (_dl_file_id_match_p (&id, &GL(dl_rtld_map).l_file_id) + || _dl_name_match_p (name, &GL(dl_rtld_map)))) + { + /* This is indeed ld.so. Create a new link_map which refers to + the real one for almost everything. */ + l = _dl_new_object (realname, name, l_type, loader, mode, nsid); + if (l == NULL) + goto fail_new; + + /* Refer to the real descriptor. */ + l->l_real = &GL(dl_rtld_map); + + /* Copy l_addr and l_ld to avoid a GDB warning with dlmopen(). */ + l->l_addr = l->l_real->l_addr; + l->l_ld = l->l_real->l_ld; + + /* No need to bump the refcount of the real object, ld.so will + never be unloaded. */ + __close_nocancel (fd); + + /* Add the map for the mirrored object to the object list. */ + _dl_add_to_namespace_list (l, nsid); + + return l; + } +#endif + if (mode & RTLD_NOLOAD) + { + /* We are not supposed to load the object unless it is already + loaded. So return now. */ + free (realname); + __close_nocancel (fd); + return NULL; + } + + /* Print debugging message. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("file=%s [%lu]; generating link map\n", name, nsid); + + /* Enter the new object in the list of loaded objects. */ + l = _dl_new_object (realname, name, l_type, loader, mode, nsid); + if (__glibc_unlikely (l == NULL)) + { +#ifdef SHARED + fail_new: +#endif + errstring = N_("cannot create shared object descriptor"); + goto lose_errno; + } + + if (_ld_map_object_1 (l, fd, fbp, mode, loader, stack_endp, &errval, + &errstring)) + goto lose; + + /* We are done mapping in the file. We no longer need the descriptor. */ + if (__glibc_unlikely (__close_nocancel (fd) != 0)) + { + errstring = N_("cannot close file descriptor"); + goto lose_errno; + } + /* Signal that we closed the file. */ + fd = -1; + + _ld_map_object_2 (l, mode, id, origname, nsid, r, &make_consistent); return l; } - + /* Print search path. */ static void print_search_path (struct r_search_path_elem **list, From patchwork Fri Mar 17 06:32:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758088 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=yZ0tG0el; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDrp0BHyz1yWs for ; Fri, 17 Mar 2023 17:35:06 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 07623384F030 for ; Fri, 17 Mar 2023 06:35:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 07623384F030 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034904; bh=eL/i2Lop1kqU70siUdpcql0T8V3cfsz/8XKeIhnkt4E=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=yZ0tG0elYe5gCdQXYiqblIrXMefagokTTXyueixnro3SIRPN5Hec98ENggPikQJwQ ZL5pM/fe8TRJCSti3S+fgRu4uH7eZPl/gU8AP/I4Icr3fP4QQ7hdZqU+JRnKNJCB48 AqFMZHHp24NWSMeXrzkQzVsZuBYqPd+dTI0h0EW0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward101o.mail.yandex.net (forward101o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::601]) by sourceware.org (Postfix) with ESMTPS id 8151A384F01F for ; Fri, 17 Mar 2023 06:34:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8151A384F01F Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward101o.mail.yandex.net (Yandex) with ESMTP id D2CA1369E258 for ; Fri, 17 Mar 2023 09:32:32 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-8xgu8J2F; Fri, 17 Mar 2023 09:32:32 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 05/11] elf: split open_verify() into reusable parts Date: Fri, 17 Mar 2023 11:32:04 +0500 Message-Id: <20230317063210.4118076-6-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" This is almost a mechanical refactoring that splits open_verify() into 2 parts. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 337 ++++++++++++++++++++++++++------------------------ 1 file changed, 175 insertions(+), 162 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 9e0e63b9a3..353dc2aa13 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1598,19 +1598,11 @@ print_search_path (struct r_search_path_elem **list, else _dl_debug_printf_c ("\t\t(%s)\n", what); } - -/* Open a file and verify it is an ELF file for this architecture. We - ignore only ELF files for other architectures. Non-ELF files and - ELF files with different header information cause fatal errors since - this could mean there is something wrong in the installation and the - user might want to know about this. - If FD is not -1, then the file is already open and FD refers to it. - In that case, FD is consumed for both successful and error returns. */ static int -open_verify (const char *name, int fd, - struct filebuf *fbp, struct link_map *loader, - int whatcode, int mode, bool *found_other_class, bool free_name) +do_open_verify (const char *name, int fd, + struct filebuf *fbp, struct link_map *loader, + bool *found_other_class, bool free_name) { /* This is the expected ELF header. */ #define ELF32_CLASS ELFCLASS32 @@ -1637,7 +1629,170 @@ open_verify (const char *name, int fd, /* Initialize it to make the compiler happy. */ const char *errstring = NULL; int errval = 0; + ElfW(Ehdr) *ehdr; + ElfW(Phdr) *phdr; + size_t maplength; + + /* We successfully opened the file. Now verify it is a file + we can use. */ + __set_errno (0); + fbp->len = 0; + assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr))); + /* Read in the header. */ + do + { + ssize_t retlen = __read_nocancel (fd, fbp->buf + fbp->len, + sizeof (fbp->buf) - fbp->len); + if (retlen <= 0) + break; + fbp->len += retlen; + } + while (__glibc_unlikely (fbp->len < sizeof (ElfW(Ehdr)))); + + /* This is where the ELF header is loaded. */ + ehdr = (ElfW(Ehdr) *) fbp->buf; + + /* Now run the tests. */ + if (__glibc_unlikely (fbp->len < (ssize_t) sizeof (ElfW(Ehdr)))) + { + errval = errno; + errstring = (errval == 0 + ? N_("file too short") : N_("cannot read file data")); + lose: + if (free_name) + { + char *realname = (char *) name; + name = strdupa (realname); + free (realname); + } + _dl_signal_error (errval, name, NULL, errstring); + return -1; + } + + /* See whether the ELF header is what we expect. */ + if (__glibc_unlikely (! VALID_ELF_HEADER (ehdr->e_ident, expected, + EI_ABIVERSION) + || !VALID_ELF_ABIVERSION (ehdr->e_ident[EI_OSABI], + ehdr->e_ident[EI_ABIVERSION]) + || memcmp (&ehdr->e_ident[EI_PAD], + &expected[EI_PAD], + EI_NIDENT - EI_PAD) != 0)) + { + /* Something is wrong. */ + const Elf32_Word *magp = (const void *) ehdr->e_ident; + if (*magp != +#if BYTE_ORDER == LITTLE_ENDIAN + ((ELFMAG0 << (EI_MAG0 * 8)) + | (ELFMAG1 << (EI_MAG1 * 8)) + | (ELFMAG2 << (EI_MAG2 * 8)) + | (ELFMAG3 << (EI_MAG3 * 8))) +#else + ((ELFMAG0 << (EI_MAG3 * 8)) + | (ELFMAG1 << (EI_MAG2 * 8)) + | (ELFMAG2 << (EI_MAG1 * 8)) + | (ELFMAG3 << (EI_MAG0 * 8))) +#endif + ) + errstring = N_("invalid ELF header"); + + else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS)) + { + /* This is not a fatal error. On architectures where + 32-bit and 64-bit binaries can be run this might + happen. */ + *found_other_class = true; + __set_errno (ENOENT); + return -1; + } + else if (ehdr->e_ident[EI_DATA] != byteorder) + { + if (BYTE_ORDER == BIG_ENDIAN) + errstring = N_("ELF file data encoding not big-endian"); + else + errstring = N_("ELF file data encoding not little-endian"); + } + else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) + errstring + = N_("ELF file version ident does not match current one"); + /* XXX We should be able so set system specific versions which are + allowed here. */ + else if (!VALID_ELF_OSABI (ehdr->e_ident[EI_OSABI])) + errstring = N_("ELF file OS ABI invalid"); + else if (!VALID_ELF_ABIVERSION (ehdr->e_ident[EI_OSABI], + ehdr->e_ident[EI_ABIVERSION])) + errstring = N_("ELF file ABI version invalid"); + else if (memcmp (&ehdr->e_ident[EI_PAD], &expected[EI_PAD], + EI_NIDENT - EI_PAD) != 0) + errstring = N_("nonzero padding in e_ident"); + else + /* Otherwise we don't know what went wrong. */ + errstring = N_("internal error"); + + goto lose; + } + + if (__glibc_unlikely (ehdr->e_version != EV_CURRENT)) + { + errstring = N_("ELF file version does not match current one"); + goto lose; + } + if (! __glibc_likely (elf_machine_matches_host (ehdr))) + { + __set_errno (ENOENT); + return -1; + } + else if (__glibc_unlikely (ehdr->e_type != ET_DYN + && ehdr->e_type != ET_EXEC)) + { + errstring = N_("only ET_DYN and ET_EXEC can be loaded"); + goto lose; + } + else if (__glibc_unlikely (ehdr->e_phentsize != sizeof (ElfW(Phdr)))) + { + errstring = N_("ELF file's phentsize not the expected size"); + goto lose; + } + + maplength = ehdr->e_phnum * sizeof (ElfW(Phdr)); + if (ehdr->e_phoff + maplength <= (size_t) fbp->len) + phdr = (void *) (fbp->buf + ehdr->e_phoff); + else + { + phdr = alloca (maplength); + if ((size_t) __pread64_nocancel (fd, (void *) phdr, maplength, + ehdr->e_phoff) != maplength) + { + errval = errno; + errstring = N_("cannot read file data"); + goto lose; + } + } + + if (__glibc_unlikely (elf_machine_reject_phdr_p + (phdr, ehdr->e_phnum, fbp->buf, fbp->len, + loader, -1))) + { + __set_errno (ENOENT); + return -1; + } + + return 0; +} + + +/* Open a file and verify it is an ELF file for this architecture. We + ignore only ELF files for other architectures. Non-ELF files and + ELF files with different header information cause fatal errors since + this could mean there is something wrong in the installation and the + user might want to know about this. + If FD is not -1, then the file is already open and FD refers to it. + In that case, FD is consumed for both successful and error returns. */ +static int +open_verify (const char *name, int fd, + struct filebuf *fbp, struct link_map *loader, + int whatcode, int mode, bool *found_other_class, bool free_name) +{ #ifdef SHARED /* Give the auditing libraries a chance. */ if (__glibc_unlikely (GLRO(dl_naudit) > 0)) @@ -1663,161 +1818,19 @@ open_verify (const char *name, int fd, if (fd != -1) { - ElfW(Ehdr) *ehdr; - ElfW(Phdr) *phdr; - size_t maplength; - - /* We successfully opened the file. Now verify it is a file - we can use. */ - __set_errno (0); - fbp->len = 0; - assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr))); - /* Read in the header. */ - do - { - ssize_t retlen = __read_nocancel (fd, fbp->buf + fbp->len, - sizeof (fbp->buf) - fbp->len); - if (retlen <= 0) - break; - fbp->len += retlen; - } - while (__glibc_unlikely (fbp->len < sizeof (ElfW(Ehdr)))); - - /* This is where the ELF header is loaded. */ - ehdr = (ElfW(Ehdr) *) fbp->buf; - - /* Now run the tests. */ - if (__glibc_unlikely (fbp->len < (ssize_t) sizeof (ElfW(Ehdr)))) - { - errval = errno; - errstring = (errval == 0 - ? N_("file too short") : N_("cannot read file data")); - lose: - if (free_name) - { - char *realname = (char *) name; - name = strdupa (realname); - free (realname); - } - __close_nocancel (fd); - _dl_signal_error (errval, name, NULL, errstring); - } - - /* See whether the ELF header is what we expect. */ - if (__glibc_unlikely (! VALID_ELF_HEADER (ehdr->e_ident, expected, - EI_ABIVERSION) - || !VALID_ELF_ABIVERSION (ehdr->e_ident[EI_OSABI], - ehdr->e_ident[EI_ABIVERSION]) - || memcmp (&ehdr->e_ident[EI_PAD], - &expected[EI_PAD], - EI_NIDENT - EI_PAD) != 0)) - { - /* Something is wrong. */ - const Elf32_Word *magp = (const void *) ehdr->e_ident; - if (*magp != -#if BYTE_ORDER == LITTLE_ENDIAN - ((ELFMAG0 << (EI_MAG0 * 8)) - | (ELFMAG1 << (EI_MAG1 * 8)) - | (ELFMAG2 << (EI_MAG2 * 8)) - | (ELFMAG3 << (EI_MAG3 * 8))) -#else - ((ELFMAG0 << (EI_MAG3 * 8)) - | (ELFMAG1 << (EI_MAG2 * 8)) - | (ELFMAG2 << (EI_MAG1 * 8)) - | (ELFMAG3 << (EI_MAG0 * 8))) -#endif - ) - errstring = N_("invalid ELF header"); - - else if (ehdr->e_ident[EI_CLASS] != ELFW(CLASS)) - { - /* This is not a fatal error. On architectures where - 32-bit and 64-bit binaries can be run this might - happen. */ - *found_other_class = true; - __close_nocancel (fd); - __set_errno (ENOENT); - return -1; - } - else if (ehdr->e_ident[EI_DATA] != byteorder) - { - if (BYTE_ORDER == BIG_ENDIAN) - errstring = N_("ELF file data encoding not big-endian"); - else - errstring = N_("ELF file data encoding not little-endian"); - } - else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) - errstring - = N_("ELF file version ident does not match current one"); - /* XXX We should be able so set system specific versions which are - allowed here. */ - else if (!VALID_ELF_OSABI (ehdr->e_ident[EI_OSABI])) - errstring = N_("ELF file OS ABI invalid"); - else if (!VALID_ELF_ABIVERSION (ehdr->e_ident[EI_OSABI], - ehdr->e_ident[EI_ABIVERSION])) - errstring = N_("ELF file ABI version invalid"); - else if (memcmp (&ehdr->e_ident[EI_PAD], &expected[EI_PAD], - EI_NIDENT - EI_PAD) != 0) - errstring = N_("nonzero padding in e_ident"); - else - /* Otherwise we don't know what went wrong. */ - errstring = N_("internal error"); - - goto lose; - } - - if (__glibc_unlikely (ehdr->e_version != EV_CURRENT)) - { - errstring = N_("ELF file version does not match current one"); - goto lose; - } - if (! __glibc_likely (elf_machine_matches_host (ehdr))) - { - __close_nocancel (fd); - __set_errno (ENOENT); - return -1; - } - else if (__glibc_unlikely (ehdr->e_type != ET_DYN - && ehdr->e_type != ET_EXEC)) - { - errstring = N_("only ET_DYN and ET_EXEC can be loaded"); - goto lose; - } - else if (__glibc_unlikely (ehdr->e_phentsize != sizeof (ElfW(Phdr)))) - { - errstring = N_("ELF file's phentsize not the expected size"); - goto lose; - } - - maplength = ehdr->e_phnum * sizeof (ElfW(Phdr)); - if (ehdr->e_phoff + maplength <= (size_t) fbp->len) - phdr = (void *) (fbp->buf + ehdr->e_phoff); - else - { - phdr = alloca (maplength); - if ((size_t) __pread64_nocancel (fd, (void *) phdr, maplength, - ehdr->e_phoff) != maplength) - { - errval = errno; - errstring = N_("cannot read file data"); - goto lose; - } - } - - if (__glibc_unlikely (elf_machine_reject_phdr_p - (phdr, ehdr->e_phnum, fbp->buf, fbp->len, - loader, fd))) - { - __close_nocancel (fd); - __set_errno (ENOENT); - return -1; - } - + int err = do_open_verify (name, fd, fbp, loader, + found_other_class, + free_name); + if (err) + { + __close_nocancel (fd); + return -1; + } } return fd; } - + /* Try to open NAME in one of the directories in *DIRSP. Return the fd, or -1. If successful, fill in *REALNAME with the malloc'd full directory name. If it turns out From patchwork Fri Mar 17 06:32:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758084 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=qYCN9CkD; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDpW6SZvz2473 for ; Fri, 17 Mar 2023 17:33:07 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D7E303851405 for ; Fri, 17 Mar 2023 06:33:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D7E303851405 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034785; bh=ZNJh/PMadX/JJdXrTT94aYfnaHtH+vBKczuQQv+lyPY=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=qYCN9CkDdXtn6JETR0TRSd4sWzgiDz+6jyaYxkVAxe5b0cXaZtTwm/5cwRSqHIBfu LbK/HkmCJNQGRrN165O9JE6QpP7Ue8WCfblu2n8bQlhFi4zlAOR2jGGEJAEcNoJPWl ExjDkiFciqo0tRIWtL/1ThxD5qWxy9jrTz75fjpA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward101j.mail.yandex.net (forward101j.mail.yandex.net [IPv6:2a02:6b8:0:801:2::101]) by sourceware.org (Postfix) with ESMTPS id A611238555A0 for ; Fri, 17 Mar 2023 06:32:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A611238555A0 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward101j.mail.yandex.net (Yandex) with ESMTP id B7E6969B7C7F for ; Fri, 17 Mar 2023 09:32:33 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-fRG4jtp9; Fri, 17 Mar 2023 09:32:33 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 06/11] elf: load elf hdr fully in open_verify() Date: Fri, 17 Mar 2023 11:32:05 +0500 Message-Id: <20230317063210.4118076-7-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" open_verify() reads an elf header, putting only the ehdr part into the filebuf, and reading the rest of the header into the alloca() space. This requires _ld_map_object_1() (former _ld_map_object_from_fd()) to read parts of an elf header again, getting only ehdr from filebuf. This patch makes filebuf sizeable and reads an entire elf header there, avoiding the code duplication and getting rid of file reads in _ld_map_object_1(). The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 122 +++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 56 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 353dc2aa13..45656d8fa5 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -55,7 +55,8 @@ struct filebuf #else # define FILEBUF_SIZE 832 #endif - char buf[FILEBUF_SIZE] __attribute__ ((aligned (__alignof (ElfW(Ehdr))))); + ssize_t allocated; + char *buf; }; #include "dynamic-link.h" @@ -124,6 +125,29 @@ static const size_t system_dirs_len[] = }; #define nsystem_dirs_len array_length (system_dirs_len) +static void +filebuf_done (struct filebuf *fb) +{ + free (fb->buf); + fb->buf = NULL; + fb->allocated = 0; +} + +static bool +filebuf_ensure (struct filebuf *fb, size_t size) +{ + bool ret = false; + + if (size > fb->allocated) + { + size_t new_len = size + FILEBUF_SIZE; + fb->buf = realloc (fb->buf, new_len); + fb->allocated = new_len; + ret = true; + } + return ret; +} + static bool is_trusted_path_normalize (const char *path, size_t len) { @@ -955,18 +979,8 @@ _ld_map_object_1 (struct link_map *l, int fd, l->l_phnum = header->e_phnum; maplength = header->e_phnum * sizeof (ElfW(Phdr)); - if (header->e_phoff + maplength <= (size_t) fbp->len) - phdr = (void *) (fbp->buf + header->e_phoff); - else - { - phdr = alloca (maplength); - if ((size_t) __pread64_nocancel (fd, (void *) phdr, maplength, - header->e_phoff) != maplength) - { - errstring = N_("cannot read file data"); - goto lose_errno; - } - } + assert (header->e_phoff + maplength <= (size_t) fbp->len); + phdr = (void *) (fbp->buf + header->e_phoff); /* On most platforms presume that PT_GNU_STACK is absent and the stack is * executable. Other platforms default to a nonexecutable stack and don't @@ -1629,31 +1643,16 @@ do_open_verify (const char *name, int fd, /* Initialize it to make the compiler happy. */ const char *errstring = NULL; int errval = 0; - ElfW(Ehdr) *ehdr; + ElfW(Ehdr) _ehdr; + ElfW(Ehdr) *ehdr = &_ehdr; ElfW(Phdr) *phdr; size_t maplength; /* We successfully opened the file. Now verify it is a file we can use. */ __set_errno (0); - fbp->len = 0; - assert (sizeof (fbp->buf) > sizeof (ElfW(Ehdr))); /* Read in the header. */ - do - { - ssize_t retlen = __read_nocancel (fd, fbp->buf + fbp->len, - sizeof (fbp->buf) - fbp->len); - if (retlen <= 0) - break; - fbp->len += retlen; - } - while (__glibc_unlikely (fbp->len < sizeof (ElfW(Ehdr)))); - - /* This is where the ELF header is loaded. */ - ehdr = (ElfW(Ehdr) *) fbp->buf; - - /* Now run the tests. */ - if (__glibc_unlikely (fbp->len < (ssize_t) sizeof (ElfW(Ehdr)))) + if (__pread64_nocancel (fd, &_ehdr, sizeof(_ehdr), 0) != sizeof(_ehdr)) { errval = errno; errstring = (errval == 0 @@ -1754,19 +1753,17 @@ do_open_verify (const char *name, int fd, } maplength = ehdr->e_phnum * sizeof (ElfW(Phdr)); - if (ehdr->e_phoff + maplength <= (size_t) fbp->len) - phdr = (void *) (fbp->buf + ehdr->e_phoff); - else + filebuf_ensure (fbp, maplength + ehdr->e_phoff); + if ((size_t) __pread64_nocancel (fd, fbp->buf, maplength + + ehdr->e_phoff, 0) != maplength + + ehdr->e_phoff) { - phdr = alloca (maplength); - if ((size_t) __pread64_nocancel (fd, (void *) phdr, maplength, - ehdr->e_phoff) != maplength) - { - errval = errno; - errstring = N_("cannot read file data"); - goto lose; - } + errval = errno; + errstring = N_("cannot read file data"); + goto lose; } + fbp->len = maplength + ehdr->e_phoff; + phdr = (void *) (fbp->buf + ehdr->e_phoff); if (__glibc_unlikely (elf_machine_reject_phdr_p (phdr, ehdr->e_phnum, fbp->buf, fbp->len, @@ -1992,16 +1989,16 @@ open_path (const char *name, size_t namelen, int mode, /* Map in the shared object file NAME. */ -struct link_map * -_dl_map_object (struct link_map *loader, const char *name, - int type, int trace_mode, int mode, Lmid_t nsid) +static struct link_map * +___dl_map_object (struct link_map *loader, const char *name, + int type, int trace_mode, int mode, Lmid_t nsid, + struct filebuf *fbp) { int fd; const char *origname = NULL; char *realname; char *name_copy; struct link_map *l; - struct filebuf fb; assert (nsid >= 0); assert (nsid < GL(dl_nns)); @@ -2091,7 +2088,7 @@ _dl_map_object (struct link_map *loader, const char *name, { fd = open_path (name, namelen, mode, &l->l_rpath_dirs, - &realname, &fb, loader, LA_SER_RUNPATH, + &realname, fbp, loader, LA_SER_RUNPATH, &found_other_class); if (fd != -1) break; @@ -2107,7 +2104,7 @@ _dl_map_object (struct link_map *loader, const char *name, "RPATH")) fd = open_path (name, namelen, mode, &main_map->l_rpath_dirs, - &realname, &fb, loader ?: main_map, LA_SER_RUNPATH, + &realname, fbp, loader ?: main_map, LA_SER_RUNPATH, &found_other_class); /* Also try DT_RUNPATH in the executable for LD_AUDIT dlopen @@ -2121,7 +2118,7 @@ _dl_map_object (struct link_map *loader, const char *name, if (cache_rpath (main_map, &l_rpath_dirs, DT_RUNPATH, "RUNPATH")) fd = open_path (name, namelen, mode, &l_rpath_dirs, - &realname, &fb, loader ?: main_map, + &realname, fbp, loader ?: main_map, LA_SER_RUNPATH, &found_other_class); } } @@ -2129,7 +2126,7 @@ _dl_map_object (struct link_map *loader, const char *name, /* Try the LD_LIBRARY_PATH environment variable. */ if (fd == -1 && __rtld_env_path_list.dirs != (void *) -1) fd = open_path (name, namelen, mode, &__rtld_env_path_list, - &realname, &fb, + &realname, fbp, loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded, LA_SER_LIBPATH, &found_other_class); @@ -2138,7 +2135,7 @@ _dl_map_object (struct link_map *loader, const char *name, && cache_rpath (loader, &loader->l_runpath_dirs, DT_RUNPATH, "RUNPATH")) fd = open_path (name, namelen, mode, - &loader->l_runpath_dirs, &realname, &fb, loader, + &loader->l_runpath_dirs, &realname, fbp, loader, LA_SER_RUNPATH, &found_other_class); if (fd == -1) @@ -2147,7 +2144,7 @@ _dl_map_object (struct link_map *loader, const char *name, if (realname != NULL) { fd = open_verify (realname, fd, - &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, + fbp, loader ?: GL(dl_ns)[nsid]._ns_loaded, LA_SER_CONFIG, mode, &found_other_class, false); if (fd == -1) @@ -2201,7 +2198,7 @@ _dl_map_object (struct link_map *loader, const char *name, if (cached != NULL) { fd = open_verify (cached, -1, - &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, + fbp, loader ?: GL(dl_ns)[nsid]._ns_loaded, LA_SER_CONFIG, mode, &found_other_class, false); if (__glibc_likely (fd != -1)) @@ -2219,7 +2216,7 @@ _dl_map_object (struct link_map *loader, const char *name, || __glibc_likely (!(l->l_flags_1 & DF_1_NODEFLIB))) && __rtld_search_dirs.dirs != (void *) -1) fd = open_path (name, namelen, mode, &__rtld_search_dirs, - &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); + &realname, fbp, l, LA_SER_DEFAULT, &found_other_class); /* Add another newline when we are tracing the library loading. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) @@ -2235,7 +2232,7 @@ _dl_map_object (struct link_map *loader, const char *name, fd = -1; else { - fd = open_verify (realname, -1, &fb, + fd = open_verify (realname, -1, fbp, loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode, &found_other_class, true); if (__glibc_unlikely (fd == -1)) @@ -2296,10 +2293,23 @@ _dl_map_object (struct link_map *loader, const char *name, } void *stack_end = __libc_stack_end; - return _dl_map_object_from_fd (name, origname, fd, &fb, realname, loader, + return _dl_map_object_from_fd (name, origname, fd, fbp, realname, loader, type, mode, &stack_end, nsid); } +struct link_map * +_dl_map_object (struct link_map *loader, const char *name, + int type, int trace_mode, + int mode, Lmid_t nsid) +{ + struct link_map *ret; + struct filebuf fb = {}; + + ret = ___dl_map_object (loader, name, type, trace_mode, mode, nsid, &fb); + filebuf_done (&fb); + return ret; +} + struct add_path_state { bool counting; From patchwork Fri Mar 17 06:32:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758091 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=qyyi9Pq4; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDsq2jdlz1yWp for ; Fri, 17 Mar 2023 17:35:59 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4A180385084C for ; Fri, 17 Mar 2023 06:35:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4A180385084C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034957; bh=I3lil+P8BERQZAw+AWZTS8jwax51srh5PnbNToh9PcE=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=qyyi9Pq4o2sFC/dEAmnJEbVYwoHj2un2X7oClXTdGZq9Bv8y3uQl5D/5zLDdXIGck EN7c2HU4AH6P9mOpUtE6KMHM7CrSts/3U714Ri8fQUhFglTleMQ+gFEQCGnfA1yXHS oqj4MGXZP2mtkw0uJoyAyLuuRO38bMo0aKbe6Slo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward107p.mail.yandex.net (forward107p.mail.yandex.net [77.88.28.115]) by sourceware.org (Postfix) with ESMTPS id EA72B3848432 for ; Fri, 17 Mar 2023 06:34:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EA72B3848432 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward107p.mail.yandex.net (Yandex) with ESMTP id 909505574FE5 for ; Fri, 17 Mar 2023 09:32:34 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-jdLVZ07v; Fri, 17 Mar 2023 09:32:34 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 07/11] elf: convert pread64 to callback in do_open_verify() Date: Fri, 17 Mar 2023 11:32:06 +0500 Message-Id: <20230317063210.4118076-8-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" This unbinds do_open_verify() from fd. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 45656d8fa5..67e4933735 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1613,10 +1613,18 @@ print_search_path (struct r_search_path_elem **list, _dl_debug_printf_c ("\t\t(%s)\n", what); } +static ssize_t +do_pread (void *arg, void *buf, size_t count, off_t offset) +{ + int fd = *(const int *) arg; + return __pread64_nocancel (fd, buf, count, offset); +} + static int -do_open_verify (const char *name, int fd, +do_open_verify (const char *name, void *fd, struct filebuf *fbp, struct link_map *loader, - bool *found_other_class, bool free_name) + bool *found_other_class, bool free_name, + __typeof (do_pread) *pread_cb) { /* This is the expected ELF header. */ #define ELF32_CLASS ELFCLASS32 @@ -1652,7 +1660,7 @@ do_open_verify (const char *name, int fd, we can use. */ __set_errno (0); /* Read in the header. */ - if (__pread64_nocancel (fd, &_ehdr, sizeof(_ehdr), 0) != sizeof(_ehdr)) + if (pread_cb (fd, &_ehdr, sizeof(_ehdr), 0) != sizeof(_ehdr)) { errval = errno; errstring = (errval == 0 @@ -1754,7 +1762,7 @@ do_open_verify (const char *name, int fd, maplength = ehdr->e_phnum * sizeof (ElfW(Phdr)); filebuf_ensure (fbp, maplength + ehdr->e_phoff); - if ((size_t) __pread64_nocancel (fd, fbp->buf, maplength + + if ((size_t) pread_cb (fd, fbp->buf, maplength + ehdr->e_phoff, 0) != maplength + ehdr->e_phoff) { @@ -1815,9 +1823,9 @@ open_verify (const char *name, int fd, if (fd != -1) { - int err = do_open_verify (name, fd, fbp, loader, + int err = do_open_verify (name, &fd, fbp, loader, found_other_class, - free_name); + free_name, do_pread); if (err) { __close_nocancel (fd); From patchwork Fri Mar 17 06:32:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758087 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=xMzEf3i5; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDqx149vz2473 for ; Fri, 17 Mar 2023 17:34:21 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1900E384F020 for ; Fri, 17 Mar 2023 06:34:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1900E384F020 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034859; bh=gZkQzrmw5u3+dXD35DI5MpEAYnrKU/MD4AURnyO3ho8=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=xMzEf3i5UjOvJ1VICO41UhkZMc324yRmC3pb3LnomuSg3//XY1G7Px71BMPkztCyC JlLUEfEtYU4lK+4a4BcuGwlbXM2EhxwTZQuJ279mFTi1igmp6VmZAYWHA0kanzS9ds BEXBqM8U5XNxsRpSGBiQUBGnj7qbc5dOqPyESiUM= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward102p.mail.yandex.net (forward102p.mail.yandex.net [77.88.28.102]) by sourceware.org (Postfix) with ESMTPS id 9A581385B536 for ; Fri, 17 Mar 2023 06:32:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9A581385B536 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward102p.mail.yandex.net (Yandex) with ESMTP id 6D3E8393F956 for ; Fri, 17 Mar 2023 09:32:35 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-MMMVhPp7; Fri, 17 Mar 2023 09:32:34 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 08/11] elf: convert _dl_map_segments's mmap() to a callback Date: Fri, 17 Mar 2023 11:32:07 +0500 Message-Id: <20230317063210.4118076-9-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" This only applies to file-based mmap. Since _dl_map_segment() was converted to anonymous mmap, only 1 place is now converted to a callback. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 19 ++++++++++++++----- elf/dl-load.h | 8 ++++++-- elf/dl-map-segments.h | 6 +++--- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 67e4933735..17f16c7dd0 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -954,11 +954,12 @@ _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph) } static int -_ld_map_object_1 (struct link_map *l, int fd, +_ld_map_object_1 (struct link_map *l, void *fd, struct filebuf *fbp, int mode, struct link_map *loader, void **stack_endp, int *errval_p, - const char **errstring_p) + const char **errstring_p, + __typeof (do_mmap) *m_map) { const ElfW(Ehdr) *header; const ElfW(Phdr) *phdr; @@ -1158,7 +1159,7 @@ _ld_map_object_1 (struct link_map *l, int fd, l_map_start, l_map_end, l_addr, l_contiguous, l_text_end, l_phdr */ errstring = _dl_map_segments (l, fd, header, type, loadcmds, nloadcmds, - maplength, has_holes, loader); + maplength, has_holes, loader, m_map); if (__glibc_unlikely (errstring != NULL)) { /* Mappings can be in an inconsistent state: avoid unmap. */ @@ -1425,6 +1426,14 @@ _ld_map_object_2 (struct link_map *l, int mode, /* Map in the shared object NAME, actually located in REALNAME, and already opened on FD. */ +static void * +do_mmap (void *addr, size_t length, int prot, int flags, + void *arg, off_t offset) +{ + int fd = *(const int *) arg; + return __mmap (addr, length, prot, flags, fd, offset); +} + #ifndef EXTERNAL_MAP_FROM_FD static #endif @@ -1554,8 +1563,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, goto lose_errno; } - if (_ld_map_object_1 (l, fd, fbp, mode, loader, stack_endp, &errval, - &errstring)) + if (_ld_map_object_1 (l, &fd, fbp, mode, loader, stack_endp, &errval, + &errstring, do_mmap)) goto lose; /* We are done mapping in the file. We no longer need the descriptor. */ diff --git a/elf/dl-load.h b/elf/dl-load.h index ecf6910c68..eff5146acd 100644 --- a/elf/dl-load.h +++ b/elf/dl-load.h @@ -80,6 +80,9 @@ struct loadcmd int prot; /* PROT_* bits. */ }; +static void * +do_mmap (void *addr, size_t length, int prot, int flags, + void *arg, off_t offset); /* This is a subroutine of _dl_map_segments. It should be called for each load command, some time after L->l_addr has been set correctly. It is @@ -113,13 +116,14 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header, The file defines this function. The canonical implementation in elf/dl-map-segments.h might be replaced by a sysdeps version. */ -static const char *_dl_map_segments (struct link_map *l, int fd, +static const char *_dl_map_segments (struct link_map *l, void *fd, const ElfW(Ehdr) *header, int type, const struct loadcmd loadcmds[], size_t nloadcmds, const size_t maplength, bool has_holes, - struct link_map *loader); + struct link_map *loader, + __typeof (do_mmap) *m_map); /* All the error message strings _dl_map_segments might return are listed here so that different implementations in different sysdeps diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index 075a1d1f4c..c5c9bb4163 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -78,11 +78,11 @@ _dl_map_segment (ElfW(Addr) mappref, size_t maplength, size_t mapalign, other use of those parts of the address space). */ static __always_inline const char * -_dl_map_segments (struct link_map *l, int fd, +_dl_map_segments (struct link_map *l, void *fd, const ElfW(Ehdr) *header, int type, const struct loadcmd loadcmds[], size_t nloadcmds, const size_t maplength, bool has_holes, - struct link_map *loader) + struct link_map *loader, __typeof (do_mmap) *m_map) { const struct loadcmd *c = loadcmds; @@ -143,7 +143,7 @@ _dl_map_segments (struct link_map *l, int fd, { if (c->mapend > c->mapstart /* Map the segment contents from the file. */ - && (__mmap ((void *) (l->l_addr + c->mapstart), + && (m_map ((void *) (l->l_addr + c->mapstart), c->mapend - c->mapstart, c->prot, MAP_FIXED|MAP_COPY|MAP_FILE, fd, c->mapoff) From patchwork Fri Mar 17 06:32:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758090 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=ScB/ouq2; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDsf21DHz1yWp for ; Fri, 17 Mar 2023 17:35:50 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3B51D384F02A for ; Fri, 17 Mar 2023 06:35:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3B51D384F02A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034948; bh=BnjWj8pXxaKazl5WJ9aaidaCifXvGXCZcSmpC9+MODY=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=ScB/ouq2MZZ5BeZuznjbD8KLNSX/k/nJvUiiEVJiH6JW3Z3Qcg8BvEGH38gWP18Av t8HaGXZLSsYu5i1I5uISvweZ/oQ37MO7evELFm4xPSUiAGDNBCJ3sTss7E4DiREQ1C BxDCCweKhpx2RQg0T/V9ySQv4ReMMGTx/Qq7XB+Y= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward103o.mail.yandex.net (forward103o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::606]) by sourceware.org (Postfix) with ESMTPS id 9DBDD38493E4 for ; Fri, 17 Mar 2023 06:35:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9DBDD38493E4 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward103o.mail.yandex.net (Yandex) with ESMTP id 4EBC310ACE91 for ; Fri, 17 Mar 2023 09:32:36 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-pG77uaIr; Fri, 17 Mar 2023 09:32:35 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 09/11] elf: call _dl_map_segment() via premap callback Date: Fri, 17 Mar 2023 11:32:08 +0500 Message-Id: <20230317063210.4118076-10-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" This allows to install custom premap callbacks in the subsequent patches. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 15 ++++++++++++--- elf/dl-load.h | 7 ++++++- elf/dl-map-segments.h | 8 +++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 17f16c7dd0..6415e2517d 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -959,7 +959,8 @@ _ld_map_object_1 (struct link_map *l, void *fd, int mode, struct link_map *loader, void **stack_endp, int *errval_p, const char **errstring_p, - __typeof (do_mmap) *m_map) + __typeof (do_mmap) *m_map, + dl_premap_t *premap) { const ElfW(Ehdr) *header; const ElfW(Phdr) *phdr; @@ -1159,7 +1160,7 @@ _ld_map_object_1 (struct link_map *l, void *fd, l_map_start, l_map_end, l_addr, l_contiguous, l_text_end, l_phdr */ errstring = _dl_map_segments (l, fd, header, type, loadcmds, nloadcmds, - maplength, has_holes, loader, m_map); + maplength, has_holes, loader, m_map, premap); if (__glibc_unlikely (errstring != NULL)) { /* Mappings can be in an inconsistent state: avoid unmap. */ @@ -1434,6 +1435,14 @@ do_mmap (void *addr, size_t length, int prot, int flags, return __mmap (addr, length, prot, flags, fd, offset); } +static void * +do_map_segment (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie) +{ + return (void *) _dl_map_segment ((ElfW(Addr)) mappref, maplength, + mapalign, prot); +} + #ifndef EXTERNAL_MAP_FROM_FD static #endif @@ -1564,7 +1573,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, } if (_ld_map_object_1 (l, &fd, fbp, mode, loader, stack_endp, &errval, - &errstring, do_mmap)) + &errstring, do_mmap, do_map_segment)) goto lose; /* We are done mapping in the file. We no longer need the descriptor. */ diff --git a/elf/dl-load.h b/elf/dl-load.h index eff5146acd..00d74979e6 100644 --- a/elf/dl-load.h +++ b/elf/dl-load.h @@ -84,6 +84,10 @@ static void * do_mmap (void *addr, size_t length, int prot, int flags, void *arg, off_t offset); +typedef void * +(dl_premap_t) (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie); + /* This is a subroutine of _dl_map_segments. It should be called for each load command, some time after L->l_addr has been set correctly. It is responsible for setting up the l_text_end and l_phdr fields. */ @@ -123,7 +127,8 @@ static const char *_dl_map_segments (struct link_map *l, void *fd, const size_t maplength, bool has_holes, struct link_map *loader, - __typeof (do_mmap) *m_map); + __typeof (do_mmap) *m_map, + dl_premap_t *premap); /* All the error message strings _dl_map_segments might return are listed here so that different implementations in different sysdeps diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index c5c9bb4163..ca5b2a85d2 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -82,7 +82,8 @@ _dl_map_segments (struct link_map *l, void *fd, const ElfW(Ehdr) *header, int type, const struct loadcmd loadcmds[], size_t nloadcmds, const size_t maplength, bool has_holes, - struct link_map *loader, __typeof (do_mmap) *m_map) + struct link_map *loader, __typeof (do_mmap) *m_map, + dl_premap_t *premap) { const struct loadcmd *c = loadcmds; @@ -104,8 +105,9 @@ _dl_map_segments (struct link_map *l, void *fd, - MAP_BASE_ADDR (l)); /* Remember which part of the address space this object uses. */ - l->l_map_start = _dl_map_segment (mappref, maplength, c->mapalign, - c->prot); + l->l_map_start = (ElfW(Addr)) premap ((void *) mappref, + maplength, c->mapalign, + c->prot, fd); if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; From patchwork Fri Mar 17 06:32:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758094 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=CpxT6WiB; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdF2Q37byz1yWs for ; Fri, 17 Mar 2023 17:43:26 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4346A3857803 for ; Fri, 17 Mar 2023 06:43:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4346A3857803 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679035404; bh=7qG3CUXD8dVr7FmP463uRDYfHaC15NHfNZ9jlK8BXhU=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=CpxT6WiBR3MVFlU9m46DC5Z+s6aDeyJSje9Y/XpLUEUmWmewTrrZ+IAoK99s/FGs6 eL47U7PzxKqY8s+rW/ccvtxW4pfnTLjzOYgdd37gSHTo5eGnZHQglYzJq2DCqtKOrv AcGsUAdC9EIwVmSzQ+LFs+NOGKAwO/AcyLr5Ae5g= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward108o.mail.yandex.net (forward108o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::206]) by sourceware.org (Postfix) with ESMTPS id D4FC93858431 for ; Fri, 17 Mar 2023 06:43:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D4FC93858431 Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward108o.mail.yandex.net (Yandex) with ESMTP id 25CFE5DD66A9 for ; Fri, 17 Mar 2023 09:32:37 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-jhfaf3On; Fri, 17 Mar 2023 09:32:36 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 10/11] elf: convert _dl_map_object to a callback Date: Fri, 17 Mar 2023 11:32:09 +0500 Message-Id: <20230317063210.4118076-11-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" Subsequent patches will add _dl_map_object_from_memory(). The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-load.c | 12 ++++++++++-- elf/dl-main.h | 9 +++++++++ elf/dl-open.c | 25 +++++++++++++++++++++---- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index 6415e2517d..4b40a92864 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -2324,8 +2324,8 @@ ___dl_map_object (struct link_map *loader, const char *name, } struct link_map * -_dl_map_object (struct link_map *loader, const char *name, - int type, int trace_mode, +__dl_map_object (struct link_map *loader, const char *name, + void *private, int type, int trace_mode, int mode, Lmid_t nsid) { struct link_map *ret; @@ -2336,6 +2336,14 @@ _dl_map_object (struct link_map *loader, const char *name, return ret; } +struct link_map * +_dl_map_object (struct link_map *loader, const char *name, + int type, int trace_mode, + int mode, Lmid_t nsid) +{ + return __dl_map_object (loader, name, NULL, type, trace_mode, mode, nsid); +} + struct add_path_state { bool counting; diff --git a/elf/dl-main.h b/elf/dl-main.h index 92766d06b4..344a87d5e8 100644 --- a/elf/dl-main.h +++ b/elf/dl-main.h @@ -104,6 +104,15 @@ struct dl_main_state bool version_info; }; +/* Open the shared object NAME and map in its segments. + LOADER's DT_RPATH is used in searching for NAME. + If the object is already opened, returns its existing map. */ +extern struct link_map * +__dl_map_object (struct link_map *loader, + const char *name, void *private, + int type, int trace_mode, int mode, + Lmid_t nsid) attribute_hidden; + /* Helper function to invoke _dl_init_paths with the right arguments from *STATE. */ static inline void diff --git a/elf/dl-open.c b/elf/dl-open.c index 91a2d8a538..f3886c21bc 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -40,6 +40,7 @@ #include #include +#include /* We must be careful not to leave us in an inconsistent state. Thus we @@ -48,6 +49,7 @@ struct dl_open_args { const char *file; + void *private; int mode; /* This is the caller of the dlopen() function. */ const void *caller_dlopen; @@ -55,6 +57,10 @@ struct dl_open_args /* Namespace ID. */ Lmid_t nsid; + struct link_map * + (*dl_map) (struct link_map *loader, const char *name, void *private, + int type, int trace_mode, int mode, Lmid_t nsid); + /* Original value of _ns_global_scope_pending_adds. Set by dl_open_worker. Only valid if nsid is a real namespace (non-negative). */ @@ -531,7 +537,7 @@ dl_open_worker_begin (void *a) /* Load the named object. */ struct link_map *new; - args->map = new = _dl_map_object (call_map, file, lt_loaded, 0, + args->map = new = args->dl_map (call_map, file, args->private, lt_loaded, 0, mode | __RTLD_CALLMAP, args->nsid); /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is @@ -818,9 +824,11 @@ dl_open_worker (void *a) new->l_name, new->l_ns, new->l_direct_opencount); } -void * -_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, - int argc, char *argv[], char *env[]) +static void * +do_dl_open (const char *file, void *private, int mode, + const void *caller_dlopen, Lmid_t nsid, + int argc, char *argv[], char *env[], + __typeof (__dl_map_object) *dl_map) { if ((mode & RTLD_BINDING_MASK) == 0) /* One of the flags must be set. */ @@ -870,10 +878,12 @@ no more namespaces available for dlmopen()")); struct dl_open_args args; args.file = file; + args.private = private; args.mode = mode; args.caller_dlopen = caller_dlopen; args.map = NULL; args.nsid = nsid; + args.dl_map = dl_map; /* args.libc_already_loaded is always assigned by dl_open_worker (before any explicit/non-local returns). */ args.argc = argc; @@ -935,6 +945,13 @@ no more namespaces available for dlmopen()")); return args.map; } +void * +_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, + int argc, char *argv[], char *env[]) +{ + return do_dl_open (file, NULL, mode, caller_dlopen, nsid, argc, argv, env, + __dl_map_object); +} void _dl_show_scope (struct link_map *l, int from) From patchwork Fri Mar 17 06:32:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 1758089 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=q2eZ3tAn; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PdDrq6Nw9z1yWp for ; Fri, 17 Mar 2023 17:35:07 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D1275384B10F for ; Fri, 17 Mar 2023 06:35:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D1275384B10F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034905; bh=jPBpuh7+5SywDlOTPnrzaKwaw3Q13Oa+Qta92KBgaPU=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=q2eZ3tAn6khpks0MHT3NvDMqgKQFtirHe5MQHGwXmfYBQVJBJarQi2h4+qbXiCozL QZzsrGA+sFXUgBR+CEfLA0rLFAtuItLYFt2jOd26lhs52AcIu7sANacXaGv2UIiniv 2SzmBUzD+qsw3iCFM7DfrB8ZhmW0BAxYOayO15+0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward104p.mail.yandex.net (forward104p.mail.yandex.net [IPv6:2a02:6b8:0:1472:2741:0:8b7:107]) by sourceware.org (Postfix) with ESMTPS id C8AB8385B53E for ; Fri, 17 Mar 2023 06:32:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C8AB8385B53E Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward104p.mail.yandex.net (Yandex) with ESMTP id 5B2223C21268 for ; Fri, 17 Mar 2023 09:32:38 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-DMIqT6ZG; Fri, 17 Mar 2023 09:32:37 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 11/11] dlfcn,elf: implement dlmem() [BZ #11767] Date: Fri, 17 Mar 2023 11:32:10 +0500 Message-Id: <20230317063210.4118076-12-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" This patch adds the following function: void *dlmem(const unsigned char *buffer, size_t size, int flags, struct dlmem_args *dlm_args); It is the same as dlopen() but allows to dynamic-link solibs from the memory buffer, rather than from a file as dlopen() does. "buffer" arg is the pointer to the solib image in memory. "size" is the solib image size. Must be smaller-or-equal to the actual buffer size. "flags" is the same flags argument used in dlopen(). "dlm_args" is an optional argument that allows to specify the load namespace and a premap callback. The idea behind the implementation is very simple: where the dlopen() would mmap() the file, dlmem() does anonymous mmap()+memcpy(). Or if premap callback is provided, then it is used to map the needed address space. This patch adds a test-case named tst-dlmem. It checks that dlmem worked by resolving the solib symbols. Then it checks the advanced functionality of creating the library duplicate. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/Makefile | 5 +- dlfcn/Versions | 3 + dlfcn/dlfcn.h | 15 ++ dlfcn/dlmem.c | 102 +++++++++++ dlfcn/glreflib1.c | 2 + dlfcn/tst-dlmem.c | 166 ++++++++++++++++++ elf/dl-load.c | 148 ++++++++++++++++ elf/dl-load.h | 3 + elf/dl-main.h | 12 ++ elf/dl-open.c | 12 ++ elf/rtld.c | 1 + include/dlfcn.h | 4 + manual/dynlink.texi | 1 + sysdeps/generic/ldsodefs.h | 9 + sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 49 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 dlfcn/dlmem.c create mode 100644 dlfcn/tst-dlmem.c diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 1fa7fea1ef..c6deef6e43 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -28,6 +28,7 @@ routines = \ dlclose \ dlerror \ dlinfo \ + dlmem \ dlmopen \ dlopen \ dlsym \ @@ -51,7 +52,8 @@ endif ifeq (yes,$(build-shared)) tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ - bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen + bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen tst-dlmem +CPPFLAGS-tst-dlmem.c += -DBUILDDIR=\"$(objpfx)\" endif modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \ defaultmod2 errmsg1mod modatexit modcxaatexit \ @@ -102,6 +104,7 @@ $(objpfx)glrefmain.out: $(objpfx)glrefmain \ $(objpfx)failtest.out: $(objpfx)failtestmod.so $(objpfx)tst-dladdr.out: $(objpfx)glreflib1.so +$(objpfx)tst-dlmem.out: $(objpfx)glreflib1.so $(objpfx)tst-dlinfo.out: $(objpfx)glreflib3.so LDFLAGS-glreflib3.so = -Wl,-rpath,: diff --git a/dlfcn/Versions b/dlfcn/Versions index cc34eb824d..b427c9c3a3 100644 --- a/dlfcn/Versions +++ b/dlfcn/Versions @@ -28,6 +28,9 @@ libc { dlsym; dlvsym; } + GLIBC_2.38 { + dlmem; + } GLIBC_PRIVATE { __libc_dlerror_result; _dlerror_run; diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h index c5d192597d..e517882ebf 100644 --- a/dlfcn/dlfcn.h +++ b/dlfcn/dlfcn.h @@ -68,6 +68,21 @@ extern void *dlsym (void *__restrict __handle, /* Like `dlopen', but request object to be allocated in a new namespace. */ extern void *dlmopen (Lmid_t __nsid, const char *__file, int __mode) __THROWNL; +/* Callback for dlmem. */ +typedef void * +(dlmem_premap_t) (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie); + +struct dlmem_args { + Lmid_t nsid; + dlmem_premap_t *premap; + void *cookie; +}; + +/* Like `dlmopen', but loads shared object from memory buffer. */ +extern void *dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args); + /* Find the run-time address in the shared object HANDLE refers to of the symbol called NAME with VERSION. */ extern void *dlvsym (void *__restrict __handle, diff --git a/dlfcn/dlmem.c b/dlfcn/dlmem.c new file mode 100644 index 0000000000..548f6f34eb --- /dev/null +++ b/dlfcn/dlmem.c @@ -0,0 +1,102 @@ +/* Load a shared object from memory. + Copyright (C) 1995-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 +#include +#include +#include + +struct _dlmem_args +{ + /* The arguments for dlmem_doit. */ + const unsigned char *buffer; + size_t size; + int mode; + struct dlmem_args *args; + /* The return value of dlmem_doit. */ + void *new; + /* Address of the caller. */ + const void *caller; +}; + +static void +dlmem_doit (void *a) +{ + struct _dlmem_args *args = (struct _dlmem_args *) a; + + if (args->mode & ~(RTLD_BINDING_MASK | RTLD_NOLOAD | RTLD_DEEPBIND + | RTLD_GLOBAL | RTLD_LOCAL | RTLD_NODELETE + | __RTLD_SPROF)) + _dl_signal_error (0, NULL, NULL, _("invalid mode parameter")); + + args->new = GLRO(dl_mem) (args->buffer, args->size, + args->mode | __RTLD_DLOPEN, + args->args, + args->caller, + __libc_argc, __libc_argv, __environ); +} + + +static void * +dlmem_implementation (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, void *dl_caller) +{ + struct _dlmem_args args; + args.buffer = buffer; + args.size = size; + args.mode = mode; + args.args = dlm_args; + args.caller = dl_caller; + + return _dlerror_run (dlmem_doit, &args) ? NULL : args.new; +} + +#ifdef SHARED +void * +___dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args) +{ + if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlmem (buffer, size, mode, dlm_args, + RETURN_ADDRESS (0)); + else + return dlmem_implementation (buffer, size, mode, dlm_args, + RETURN_ADDRESS (0)); +} +versioned_symbol (libc, ___dlmem, dlmem, GLIBC_2_38); + +#else /* !SHARED */ +/* Also used with _dlfcn_hook. */ +void * +__dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, void *dl_caller) +{ + return dlmem_implementation (buffer, size, mode, dlm_args, dl_caller); +} + +void * +___dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args) +{ + return __dlmem (buffer, size, mode, dlm_args, RETURN_ADDRESS (0)); +} +weak_alias (___dlmem, dlmem) +static_link_warning (dlmem) +#endif /* !SHARED */ diff --git a/dlfcn/glreflib1.c b/dlfcn/glreflib1.c index f26832fabe..bab3fcd1b0 100644 --- a/dlfcn/glreflib1.c +++ b/dlfcn/glreflib1.c @@ -22,3 +22,5 @@ ref1 (void) { return 42; } + +int bar = 35; diff --git a/dlfcn/tst-dlmem.c b/dlfcn/tst-dlmem.c new file mode 100644 index 0000000000..12209bfe5e --- /dev/null +++ b/dlfcn/tst-dlmem.c @@ -0,0 +1,166 @@ +/* Test for dlmem. + Copyright (C) 2000-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 +#include +#include +#include +#include +#include +#include +#include +#include + +static size_t maplen; + +static void * +premap_dlmem (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie) +{ + int fd = * (int *) cookie; + int err; + + /* See if we support such parameters. */ + if (mappref || mapalign > 4096) + return MAP_FAILED; + + fprintf (stderr, "%s\n", __func__); + + err = ftruncate (fd, maplength); + if (err) + error (EXIT_FAILURE, 0, "ftruncate() failed"); + maplen = maplength; + return mmap (NULL, maplength, prot, MAP_SHARED | MAP_FILE +#ifdef MAP_32BIT + | MAP_32BIT +#endif + , fd, 0); +} + +#define TEST_FUNCTION do_test +extern int do_test (void); + +int +do_test (void) +{ + void *handle; + void *addr; + int (*sym) (void); /* We load ref1 from glreflib1.c. */ + int *bar, *bar2; + unsigned char *addr2; + Dl_info info; + int ret; + int fd; + int num; + off_t len; + struct link_map *lm; + const char *shm_name = "/tst-dlmem"; + int shm_fd; + struct dlmem_args a; + + shm_fd = memfd_create (shm_name, 0); + if (shm_fd == -1) + error (EXIT_FAILURE, 0, "shm_open() failed"); + + fd = open (BUILDDIR "glreflib1.so", O_RDONLY); + if (fd == -1) + error (EXIT_FAILURE, 0, "cannot open: glreflib1.so"); + len = lseek (fd, 0, SEEK_END); + lseek (fd, 0, SEEK_SET); + addr = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) + error (EXIT_FAILURE, 0, "cannot mmap: glreflib1.so"); + a.nsid = LM_ID_BASE; + a.premap = premap_dlmem; + a.cookie = &shm_fd; + handle = dlmem (addr, len, RTLD_NOW | RTLD_LOCAL, &a); + if (handle == NULL) + error (EXIT_FAILURE, 0, "cannot load: glreflib1.so"); + munmap (addr, len); + close (fd); + /* Check if premap was called. */ + TEST_VERIFY (maplen != 0); + + sym = dlsym (handle, "ref1"); + if (sym == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + + memset (&info, 0, sizeof (info)); + ret = dladdr (sym, &info); + if (ret == 0) + error (EXIT_FAILURE, 0, "dladdr failed"); +#ifdef MAP_32BIT + /* Make sure MAP_32BIT worked. */ + if ((unsigned long) info.dli_fbase >= 0x100000000) + error (EXIT_FAILURE, 0, "premap audit didn't work"); +#endif + ret = dlinfo (handle, RTLD_DI_LINKMAP, &lm); + if (ret != 0) + error (EXIT_FAILURE, 0, "dlinfo failed"); + + printf ("info.dli_fname = %p (\"%s\")\n", info.dli_fname, info.dli_fname); + printf ("info.dli_fbase = %p\n", info.dli_fbase); + printf ("info.dli_sname = %p (\"%s\")\n", info.dli_sname, info.dli_sname); + printf ("info.dli_saddr = %p\n", info.dli_saddr); + printf ("lm->l_addr = %lx\n", lm->l_addr); + + if (info.dli_fname == NULL) + error (EXIT_FAILURE, 0, "dli_fname is NULL"); + if (info.dli_fbase == NULL) + error (EXIT_FAILURE, 0, "dli_fbase is NULL"); + if (info.dli_sname == NULL) + error (EXIT_FAILURE, 0, "dli_sname is NULL"); + if (info.dli_saddr == NULL) + error (EXIT_FAILURE, 0, "dli_saddr is NULL"); + + num = sym (); + if (num != 42) + error (EXIT_FAILURE, 0, "bad return from ref1"); + + /* Now try symbol duplication. */ + bar = dlsym (handle, "bar"); + if (bar == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + TEST_COMPARE (*bar, 35); + /* write another value */ +#define TEST_BAR_VAL 48 + *bar = TEST_BAR_VAL; + + /* Create second instance of the solib. */ + addr2 = mmap (NULL, maplen, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED, shm_fd, 0); + if (addr2 == MAP_FAILED) + error (EXIT_FAILURE, 0, "cannot mmap shm\n"); + /* Find our bar symbol duplicate. */ + ret = dladdr (bar, &info); + if (ret == 0) + error (EXIT_FAILURE, 0, "dladdr failed"); + bar2 = (int *) (addr2 + (info.dli_saddr - info.dli_fbase)); + /* See if we found the right one. */ + TEST_COMPARE (*bar2, TEST_BAR_VAL); + + munmap (addr2, maplen); + dlclose (handle); + + return 0; +} + + +#include diff --git a/elf/dl-load.c b/elf/dl-load.c index 4b40a92864..6ce118787f 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -75,6 +75,7 @@ struct filebuf #include #include #include +#include #include #include @@ -2344,6 +2345,153 @@ _dl_map_object (struct link_map *loader, const char *name, return __dl_map_object (loader, name, NULL, type, trace_mode, mode, nsid); } +static void * +do_mmapcpy (void *addr, size_t length, int prot, int flags, + void *arg, off_t offset) +{ + const struct dlmem_fbuf *fb = arg; + + assert (flags & MAP_FIXED); + if (__mprotect (addr, length, PROT_READ | PROT_WRITE) == -1) + return MAP_FAILED; + if (offset < fb->len) + { + size_t to_copy = length; + if (offset + to_copy > fb->len) + to_copy = fb->len - offset; + memcpy (addr, fb->buf + offset, to_copy); + } + if (__mprotect (addr, length, prot) == -1) + return MAP_FAILED; + return addr; +} + +static void * +do_dlmem_premap (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie) +{ + struct dlmem_fbuf *fb = cookie; + void *ret = MAP_FAILED; + + if (fb->dlm_args && fb->dlm_args->premap) + ret = fb->dlm_args->premap (mappref, maplength, mapalign, prot, + fb->dlm_args->cookie); + if (ret == MAP_FAILED) + ret = (void *) _dl_map_segment ((ElfW(Addr)) mappref, maplength, + mapalign, prot); + return ret; +} + +static ssize_t +do_pread_memcpy (void *arg, void *buf, size_t count, off_t offset) +{ + struct dlmem_fbuf *fb = arg; + if (offset >= fb->len) + return -1; + if (offset + count > fb->len) + count = fb->len - offset; + if (count) + memcpy (buf, fb->buf + offset, count); + return count; +} + +static struct link_map * +___dl_map_object_from_mem (struct link_map *loader, const char *name, + void *private, int type, int trace_mode, + int mode, Lmid_t nsid, struct filebuf *fbp) +{ + struct link_map *l; + int err; + /* Initialize to keep the compiler happy. */ + const char *errstring = NULL; + int errval = 0; + struct r_debug *r = _dl_debug_update (nsid); + bool make_consistent = false; + struct r_file_id id = {}; + + assert (nsid >= 0); + assert (nsid < GL(dl_nns)); + + /* Will be true if we found a DSO which is of the other ELF class. */ + bool found_other_class = false; + + err = do_open_verify (name, private, fbp, + loader ?: GL(dl_ns)[nsid]._ns_loaded, + &found_other_class, false, do_pread_memcpy); + if (err) + return NULL; + + /* In case the LOADER information has only been provided to get to + the appropriate RUNPATH/RPATH information we do not need it + anymore. */ + if (mode & __RTLD_CALLMAP) + loader = NULL; + + if (mode & RTLD_NOLOAD) + { + /* We are not supposed to load the object unless it is already + loaded. So return now. */ + return NULL; + } + + /* Print debugging message. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("dlmem [%lu]; generating link map\n", nsid); + + /* Enter the new object in the list of loaded objects. */ + l = _dl_new_object ((char *) name, name, type, loader, mode, nsid); + if (__glibc_unlikely (l == NULL)) + { + errstring = N_("cannot create shared object descriptor"); + goto lose_errno; + } + + void *stack_end = __libc_stack_end; + if (_ld_map_object_1 (l, private, fbp, mode, loader, &stack_end, &errval, + &errstring, do_mmapcpy, do_dlmem_premap)) + goto lose; + + _ld_map_object_2 (l, mode, id, NULL, nsid, r, &make_consistent); + return l; + +lose_errno: + errval = errno; +lose: + if (l != NULL && l->l_map_start != 0) + _dl_unmap_segments (l); + if (l != NULL && l->l_origin != (char *) -1l) + free ((char *) l->l_origin); + if (l != NULL && !l->l_libname->dont_free) + free (l->l_libname); + if (l != NULL && l->l_phdr_allocated) + free ((void *) l->l_phdr); + free (l); + + if (make_consistent && r != NULL) + { + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + LIBC_PROBE (map_failed, 2, nsid, r); + } + + _dl_signal_error (errval, NULL, NULL, errstring); + return NULL; +} + +struct link_map * +__dl_map_object_from_mem (struct link_map *loader, const char *name, + void *private, int type, int trace_mode, + int mode, Lmid_t nsid) +{ + struct link_map *ret; + struct filebuf fb = {}; + + ret = ___dl_map_object_from_mem (loader, name, private, type, trace_mode, + mode, nsid, &fb); + filebuf_done (&fb); + return ret; +} + struct add_path_state { bool counting; diff --git a/elf/dl-load.h b/elf/dl-load.h index 00d74979e6..20b7411027 100644 --- a/elf/dl-load.h +++ b/elf/dl-load.h @@ -107,6 +107,9 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header, - c->mapoff); } +static void * +do_mmap (void *addr, size_t length, int prot, int flags, + void *arg, off_t offset); /* This is a subroutine of _dl_map_object_from_fd. It is responsible for filling in several fields in *L: l_map_start, l_map_end, l_addr, diff --git a/elf/dl-main.h b/elf/dl-main.h index 344a87d5e8..e60fafaeb6 100644 --- a/elf/dl-main.h +++ b/elf/dl-main.h @@ -104,6 +104,13 @@ struct dl_main_state bool version_info; }; +struct dlmem_fbuf +{ + ssize_t len; + const unsigned char *buf; + struct dlmem_args *dlm_args; +}; + /* Open the shared object NAME and map in its segments. LOADER's DT_RPATH is used in searching for NAME. If the object is already opened, returns its existing map. */ @@ -112,6 +119,11 @@ __dl_map_object (struct link_map *loader, const char *name, void *private, int type, int trace_mode, int mode, Lmid_t nsid) attribute_hidden; +extern struct link_map * +__dl_map_object_from_mem (struct link_map *loader, + const char *name, void *private, + int type, int trace_mode, int mode, + Lmid_t nsid) attribute_hidden; /* Helper function to invoke _dl_init_paths with the right arguments from *STATE. */ diff --git a/elf/dl-open.c b/elf/dl-open.c index f3886c21bc..537a1e6003 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -953,6 +953,18 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, __dl_map_object); } +void * +_dl_mem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, const void *caller_dlopen, + int argc, char *argv[], char *env[]) +{ + struct dlmem_fbuf fb = { .buf = buffer, .len = size, .dlm_args = dlm_args }; + Lmid_t nsid = dlm_args ? dlm_args->nsid : LM_ID_BASE; + + return do_dl_open ("", &fb, mode, caller_dlopen, nsid, argc, argv, env, + __dl_map_object_from_mem); +} + void _dl_show_scope (struct link_map *l, int from) { diff --git a/elf/rtld.c b/elf/rtld.c index f82fbeb132..1877ec9f16 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -370,6 +370,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro = ._dl_mcount = _dl_mcount, ._dl_lookup_symbol_x = _dl_lookup_symbol_x, ._dl_open = _dl_open, + ._dl_mem = _dl_mem, ._dl_close = _dl_close, ._dl_catch_error = _dl_catch_error, ._dl_error_free = _dl_error_free, diff --git a/include/dlfcn.h b/include/dlfcn.h index ae25f05303..6205cf407d 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -100,6 +100,8 @@ struct dlfcn_hook { /* Public interfaces. */ void *(*dlopen) (const char *file, int mode, void *dl_caller); + void *(*dlmem) (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, void *dl_caller); int (*dlclose) (void *handle); void *(*dlsym) (void *handle, const char *name, void *dl_caller); void *(*dlvsym) (void *handle, const char *name, const char *version, @@ -123,6 +125,8 @@ struct dlfcn_hook the __libc_dl* functions defined in elf/dl-libc.c instead. */ extern void *__dlopen (const char *file, int mode, void *caller); +extern void *__dlmem (const unsigned char *file, size_t size, int mode, + struct dlmem_args *dlm_args, void *caller); extern void *__dlmopen (Lmid_t nsid, const char *file, int mode, void *dl_caller); extern int __dlclose (void *handle); diff --git a/manual/dynlink.texi b/manual/dynlink.texi index 6a4a50d3f0..21bc6c067c 100644 --- a/manual/dynlink.texi +++ b/manual/dynlink.texi @@ -209,6 +209,7 @@ This function is a GNU extension. @c dladdr1 @c dlclose @c dlerror +@c dlmem @c dlmopen @c dlopen @c dlsym diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index c99dad77cc..abca95b18c 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -669,6 +669,9 @@ struct rtld_global_ro struct link_map *); void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, int argc, char *argv[], char *env[]); + void *(*_dl_mem) (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, const void *caller_dlopen, + int argc, char *argv[], char *env[]); void (*_dl_close) (void *map); /* libdl in a secondary namespace (after dlopen) must use _dl_catch_error from the main namespace, so it has to be @@ -1249,6 +1252,12 @@ extern void *_dl_open (const char *name, int mode, const void *caller, Lmid_t nsid, int argc, char *argv[], char *env[]) attribute_hidden; +/* Open shared object from memory buffer. */ +extern void *_dl_mem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, const void *caller, + int argc, char *argv[], char *env[]) + attribute_hidden; + /* Free or queue for freeing scope OLD. If other threads might be in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the old scope, OLD can't be freed until no thread is using it. */ diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index ed0c4789eb..1880004336 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2326,6 +2326,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 0e2d9c3045..c4d31cabed 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2665,3 +2665,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index f1bec1978d..93b37a1e1d 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2774,6 +2774,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index aa874b88d0..9fec2308c3 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2426,3 +2426,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index afbd57da6f..bd0f04e58a 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -546,6 +546,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index e7364cd3fe..dccc49c8d6 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -543,6 +543,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 913fa59215..0df8524ac0 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2702,3 +2702,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 43af3a9811..fa4680e97a 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2651,6 +2651,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index af72f8fab0..bfb1bde49d 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2835,6 +2835,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 48cbb0fa50..e53505abe0 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2600,6 +2600,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index c15884bb0b..9f56cbdcab 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2186,3 +2186,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 3738db81df..d5443b1198 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -547,6 +547,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index ed13627752..640c8b8c4a 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2778,6 +2778,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 8357738621..79b400efc6 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2751,3 +2751,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 58c5da583d..38b4098950 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2748,3 +2748,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index d3741945cd..9a4f909a25 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2743,6 +2743,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 5319fdc204..c8b9f85fdb 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2741,6 +2741,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 1743ea6eb9..0887b67394 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2749,6 +2749,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 9b1f53c6ac..1c3a6f4bee 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2651,6 +2651,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index ae1c6ca1b5..31b23859a4 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2790,3 +2790,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index a7c572c947..59f4aa7766 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2172,3 +2172,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 074fa031a7..d715d0ae97 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2817,6 +2817,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index dfcb4bd2d5..3addcf3d17 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2850,6 +2850,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 63bbccf3f9..5365978277 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2571,6 +2571,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index ab85fd61ef..f0af576192 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2885,3 +2885,4 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index b716f5c763..941fd40ea8 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2428,3 +2428,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 774e777b65..74f58439ad 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2628,3 +2628,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 8625135c48..cf3a10aa76 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2815,6 +2815,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index d00c7eb262..2ad97f87b2 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2608,6 +2608,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index b63037241d..7c81b94953 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2658,6 +2658,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index d80055617d..0493d6b456 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2655,6 +2655,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 5be55c11d2..6fd09f6499 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2810,6 +2810,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 475fdaae15..24dbc4801f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2623,6 +2623,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 6cfb928bc8..522ca8e8aa 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2574,6 +2574,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index c735097172..42b170c805 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2680,3 +2680,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F