From patchwork Wed Dec 15 22:09:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 48992 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 992F8385841C for ; Wed, 15 Dec 2021 22:10:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 992F8385841C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1639606212; bh=lSW0RoXf8CRBoXRl7Am/ZCDlEk3rR9BLexGEXBtMdJU=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=az+bKTo+voVUNH1JWgWtQmgktj2SVrJZCG2vrOddGIWDO1uEY3+yWvJsjJv8FY1iG CcKSxtrK9cZPnfmfV+yxTLpE1JaqKjlybZce1ET09dbso57Ht4/N89xy03u3aq9CYi Ix+QMYvND5EDWOAgu0O2Q/dUEKe00PUn3ibSZbog= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 4CE803858D28 for ; Wed, 15 Dec 2021 22:09:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4CE803858D28 Received: by mail-pl1-x629.google.com with SMTP id u11so17733654plf.3 for ; Wed, 15 Dec 2021 14:09:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=lSW0RoXf8CRBoXRl7Am/ZCDlEk3rR9BLexGEXBtMdJU=; b=uvXlJxWd4mmjjHY3wvRbtFiAbh7T/aYgTNFRDVEw9+3R/E6/zDckx9NdIDAhY/KFr8 7q/mge15Lytct8bZmfgA5S6kaWNtJv+TQNETr79PAAjlXikZsniZp0g6ZuwZrnGpNYVT vwJMJlF/PD18diEU+XZAOHXFqHnEumRUN78IjZ9yB1DkhVlC+WhnY1ozae7wQQu61Mlr ddBBh2Z9AdlBQ2iLZLwnBZ6lR/DdNaE3l1s7IJndsdxpJTNrhsTWpB5n1m61T222E6KB XcNEXlcSs/BYYHQ1ctvQn0p6CLS3vZaUfyJZMF5t8jEqU/k1U5PODkwkhV809CYtxpyG 0Gtw== X-Gm-Message-State: AOAM530yqigmbTOwYvwtzyTfMi2ih8HcNWJazTpQz+LY+ON8JPvnhQx1 tisH7V9cog71XiWzGDH0ly/10g7eN1I= X-Google-Smtp-Source: ABdhPJyH1els/DSQGuPwa7hDig3Hwgr303kmmaaokM/Gwjr8oFbCTnFyAr3XVvZuZ3X5SL2NwYweww== X-Received: by 2002:a17:90a:ab02:: with SMTP id m2mr2215969pjq.169.1639606189029; Wed, 15 Dec 2021 14:09:49 -0800 (PST) Received: from gnu-cfl-2.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id np1sm7668237pjb.22.2021.12.15.14.09.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Dec 2021 14:09:48 -0800 (PST) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 41DF2420860 for ; Wed, 15 Dec 2021 14:09:47 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH] elf: Properly align all PT_LOAD segments [BZ #28676] Date: Wed, 15 Dec 2021 14:09:47 -0800 Message-Id: <20211215220947.2931046-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 X-Spam-Status: No, score=-3029.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Linker may set p_align of a PT_LOAD segment larger than p_align of the first PT_LOAD segment to satisfy a section alignment: Elf file type is DYN (Shared object file) Entry point 0x0 There are 10 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000834 0x0000000000000834 R E 0x1000 LOAD 0x0000000000000e00 0x0000000000001e00 0x0000000000001e00 0x0000000000000230 0x0000000000000230 RW 0x1000 LOAD 0x0000000000400000 0x0000000000400000 0x0000000000400000 0x0000000000000004 0x0000000000000008 RW 0x400000 ... Section to Segment mapping: Segment Sections... 00 .note.gnu.property .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 01 .init_array .fini_array .data.rel.ro .dynamic .got .got.plt 02 .data .bss We should align the first PT_LOAD segment to the maximum p_align of all PT_LOAD segments, similar to the kernel commit: commit ce81bb256a224259ab686742a6284930cbe4f1fa Author: Chris Kennelly Date: Thu Oct 15 20:12:32 2020 -0700 fs/binfmt_elf: use PT_LOAD p_align values for suitable start addres This patch includes a test with an x86-64 shared library binary created by the linker patch: https://sourceware.org/pipermail/binutils/2021-December/118893.html to verify that shared libraries with such PT_LOAD segments are mapped properly. --- elf/dl-load.c | 9 +++++++- sysdeps/x86_64/64/Makefile | 9 ++++++++ sysdeps/x86_64/64/tst-p_align1.c | 27 ++++++++++++++++++++++++ sysdeps/x86_64/64/tst-p_alignmod1.so.xz | Bin 0 -> 2212 bytes 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 sysdeps/x86_64/64/Makefile create mode 100644 sysdeps/x86_64/64/tst-p_align1.c create mode 100755 sysdeps/x86_64/64/tst-p_alignmod1.so.xz GIT binary patch literal 2212 zcmds(`9Bkk1IK5Mxf+ec6Oy^IIaYb5oC!^GJnn5~OIyr+jpRs$C!*oW@xpQ^S1n;7 zLMV4~lsT6pY>qr(d(ghmpYZ+V`^)#|&kyg{`~B1B2zkc?0{{rEOg2~p0cQl{002OQ z-f|hAZ!D~Y1DIu6CHk7AJY%M^9-OoPv9aYNe@-lJQvC>Z_J|ooyS^Tywh{A@D%M%m zq`G#Gk6Sb)PP}eD3{n9PS&n-Bf$h4Rdy=u#offT&FRw~&7%_`+ij!TSv#mwxQu!5T ziHzxwCy~J8N&e+LSNyhnV9%m!ueRfTm=nPVQ=HPY1iI$NV~iPJpB+jiJ4YI)L-LN8 zUc=k;oXv*HIPrad;gIHCudIy$Fzdd)O-uSOxs~-}kQi#$VIv5=`%g}Dp%sViVC9Br zhL6}R&i^Ag+YB&N8K25>J)2G)B+M-e1v?}Ie>$hX#Q@?aAHmAJ`zztH_iB+3#hp}n z&Aoo{dRg(wyz-n!Jv91su~tNKY~%v z_`V_$`1p~@`MMXdm1SI_u@a90$(0vzz^ESDDX#L}xy&~Ia)3Z~1z{k&3eR@4Js;A9 zx^-c!GLIYotQb&6pQ^b1R&n@CUE|U>H4@Hy-2ZNufh^cl#^^A$DQJ_o1rw&5maNzN z6Rl;X7<9^Ify<6O$ik&PdprMeGWqhgR{z4A-`4q^K-LTd&KRlbS@lcY{MCy&b;)p3 zuiD=|6)q++W(kP9vmiCUB>kh&x2*M~&0|sU;}eLhwC_2S;*-%g?^25FhYdCEt;F~8 z^AHHU>8XxZMw(J8a7N$!g9uhv2hI--(m}#c^hAFS`&6KuvW~d&^y47+L{GNL=ff?s z72@>3<0v2lQ{YQ-R=OrcVW}CuyQ!n1PRENcn%Y%BCH1TKO$aTlJzJs+!7%K; z&q@5L-MK*NmwkzC!#|V89%A*P$QKpe^*0qQ%o# zqFSy?#+WHfx7BI~lXl4P;<+fn!@>ST`!|~5l?>MlA{l%gG}J zY*??WSa|FBMbeGdOFKA%T>DozZL^v-xcjBw!@p$aoR zs*LFM#B47chM=9iCg)rUubzs15^9Uo^^0^HV)1v`>H7)Lax)>}vv0C;-(N|hyd!OC zRx#G0*1>3ZRSf)td39G>W?u<+Wpky*uu!86#8B0eS`T)afJ5IG2fAAJ{*r`=n9SOz zc+chL_e|*jNVv8!)K4H%!wK`TU85UHp9PUaxM6Th@q5dXNzVu(*(A#LP#1KDQ%UY`HFm~=B zUtia)gPQdBgL@sM{~k?pRah?KOAEjNoN(vLqxKiEh~J7B>4>2J3%mb8*gvGq>J!9o z0HpxtBBM~4&z89j{XWpbimXuY0uOuNgBh&r_U^W9EfU44eOH&V*}2Q0UwQvL$l(&gk3<{s+_$f)bhpMV~_0dJK}|MN5T8~6m+9f z{Y!%r){pM5{dnFohd37rfmDTMFAmr3U9tQ&FjEhYsBM|9!x?lzm7AV7_?A)L`mi`+ zlSCPZ@pm-$Dz1`(uMMI$?Y2u4=`^8VIk6@~SYun5)jEK^fO9<4T>7Wtmyw@mu_x`$ z6giENJT_IfhpyS0J)eQAuQNRfn2Xq>$rQy@ROdP?BuR1=T0O#?nCGxezt+126K)%PXLli!BHdq2Pm&n2_c$n_-WYSCpiMSL@)A+ z9{K>)u3H(IwsuDl_^N8PaA{HRlbNGPi(go=Rr-z}f5wYSe&*}sj+?V*OL)_@Im&W> z)?W5~c}u1F2e!Vt5(&~B_SBnp6X=qmYs|=t(cD(;O3<2YA2!I{BYtNFo0gKE1fEZc znZ4Ys1(9nbf{0&1;>EFG5xJ-q`W=)8@^)yAY8FNN`c9&FMqKDZ28}#r`Alc;Sg2-H qNv_FN+`oV0UF=ghlxt7`5a3JGGZTPS>G<$h-987ve>Z>-8uK4jZbKCS literal 0 HcmV?d00001 diff --git a/elf/dl-load.c b/elf/dl-load.c index 721593135e..e61515771a 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1101,6 +1101,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, size_t nloadcmds = 0; bool has_holes = false; bool empty_dynamic = false; + ElfW(Addr) p_align_max = 0; /* The struct is initialized to zero so this is not necessary: l->l_ld = 0; @@ -1151,7 +1152,9 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize)); c->dataend = ph->p_vaddr + ph->p_filesz; c->allocend = ph->p_vaddr + ph->p_memsz; - c->mapalign = ph->p_align; + /* Remember the maximum p_align. */ + if (ph->p_align > p_align_max) + p_align_max = ph->p_align; c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize)); /* Determine whether there is a gap between the last segment @@ -1226,6 +1229,10 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd, goto lose; } + /* Align all PT_LOAD segments to the maximum p_align. */ + for (size_t i = 0; i < nloadcmds; i++) + loadcmds[i].mapalign = p_align_max; + /* dlopen of an executable is not valid because it is not possible to perform proper relocations, handle static TLS, or run the ELF constructors. For PIE, the check needs the dynamic diff --git a/sysdeps/x86_64/64/Makefile b/sysdeps/x86_64/64/Makefile new file mode 100644 index 0000000000..90e8ead42d --- /dev/null +++ b/sysdeps/x86_64/64/Makefile @@ -0,0 +1,9 @@ +ifeq ($(subdir),elf) +tests += tst-p_align1 + +$(objpfx)tst-p_align1: $(objpfx)tst-p_alignmod1.so + +$(objpfx)tst-p_alignmod1.so: $(..)sysdeps/x86_64/64/tst-p_alignmod1.so.xz + cp -f $< $(objpfx) + unxz -f $(objpfx)tst-p_alignmod1.so.xz +endif diff --git a/sysdeps/x86_64/64/tst-p_align1.c b/sysdeps/x86_64/64/tst-p_align1.c new file mode 100644 index 0000000000..cab9793220 --- /dev/null +++ b/sysdeps/x86_64/64/tst-p_align1.c @@ -0,0 +1,27 @@ +/* Check different alignments of PT_LOAD segments in a shared library. + Copyright (C) 2021 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 + . */ + +extern int do_load_test (void); + +static int +do_test (void) +{ + return do_load_test (); +} + +#include diff --git a/sysdeps/x86_64/64/tst-p_alignmod1.so.xz b/sysdeps/x86_64/64/tst-p_alignmod1.so.xz new file mode 100755 index 0000000000000000000000000000000000000000..dfb8f733f079a39305ba3a39bca67eb41bdc2e8a