From patchwork Thu May 18 08:28:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 69572 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 239B838432D3 for ; Thu, 18 May 2023 08:30:10 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward103c.mail.yandex.net (forward103c.mail.yandex.net [178.154.239.214]) by sourceware.org (Postfix) with ESMTPS id 5FB403858401 for ; Thu, 18 May 2023 08:29:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5FB403858401 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=yandex.ru Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=yandex.ru Received: from mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:1186:0:640:38cb:0]) by forward103c.mail.yandex.net (Yandex) with ESMTP id 5F1FB60038 for ; Thu, 18 May 2023 11:29:36 +0300 (MSK) Received: by mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net (smtp/Yandex) with ESMTPSA id XTYe39MDZ0U0-tVq8fXHb; Thu, 18 May 2023 11:29:35 +0300 X-Yandex-Fwd: 1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1684398576; bh=iHrAj+A96jpxuZEsITgfoiq2qX9luYidOz5DXAZ/4Lk=; h=Message-Id:Date:In-Reply-To:Cc:Subject:References:To:From; b=GvAz1Zz/4Fwtiaico/7YVEbD67sXOCKa8TZmFG0socDaHA5bBBcZr+bZccj5qIPR2 m33QXTqoIud3+6/quMNsOPBQfvR7zoaCdlW2H57jAtCH6XjawUZwXXjqBFloSK1wqv Q3W3z+/1bqcs35TuNt8EBWB/qkdViH+azEu8eiPE= Authentication-Results: mail-nwsmtp-smtp-production-main-91.iva.yp-c.yandex.net; dkim=pass header.i=@yandex.ru From: Stas Sergeev To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 01/14] elf: switch _dl_map_segment() to anonymous mapping Date: Thu, 18 May 2023 13:28:41 +0500 Message-Id: <20230518082854.3903342-2-stsp2@yandex.ru> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230518082854.3903342-1-stsp2@yandex.ru> References: <20230518082854.3903342-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-10.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, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , Errors-To: libc-alpha-bounces+patchwork=sourceware.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. Use PROT_READ|PROT_WRITE as a protection. _dl_map_segments() later sets the proper protection for both file-mapped and anonymous parts. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- elf/dl-map-segments.h | 69 ++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/elf/dl-map-segments.h b/elf/dl-map-segments.h index 504cfc0a41..ed7675cabf 100644 --- a/elf/dl-map-segments.h +++ b/elf/dl-map-segments.h @@ -22,18 +22,22 @@ /* 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) { - 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; + /* MAP_COPY is a special flag combination for solibs. */ + unsigned int map_flags = MAP_ANONYMOUS | MAP_COPY; + unsigned int prot = PROT_READ | PROT_WRITE; + + 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 +45,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 +100,7 @@ _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); if (__glibc_unlikely ((void *) l->l_map_start == MAP_FAILED)) return DL_MAP_SEGMENTS_ERROR_MAP_SEGMENT; @@ -123,14 +125,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 +145,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)