From patchwork Tue Dec 21 03:16:15 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: 49132 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 61D5B3858415 for ; Tue, 21 Dec 2021 03:25:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 61D5B3858415 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1640057136; bh=vzudlVICs35gnMSFQrpfR81AVXPAPeU/mcMd6Q1yirc=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=GQToq3K5koiKuda4Bpq3BCVcOCa1w1bOEiykrzRWwfO/kGsabuSXGfF0t+2mQoixp 9iTefvznHmJSkokyMjh8nyLmXgdVr9KJ6lDRNjyBoXDfcGnNxMCgtNTeK84zn05PsU A1aT9Oo1j5cuBHg1kK0lZaZlpZkQSlANuSOJFoXw= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by sourceware.org (Postfix) with ESMTPS id 139853858426 for ; Tue, 21 Dec 2021 03:25:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 139853858426 Received: by mail-pj1-x1035.google.com with SMTP id f18-20020a17090aa79200b001ad9cb23022so1872546pjq.4 for ; Mon, 20 Dec 2021 19:25:15 -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=vzudlVICs35gnMSFQrpfR81AVXPAPeU/mcMd6Q1yirc=; b=OwVKxPpn6poTEC8eIDJPlQk+db6ZO/U3EI46wEwU7+4ZLoxfEg4s1p/d80jHBAJC9X GTzn8AbPHbJyjL65cLd1+m8ux1+n53no3+osVSNgt8X4Y2j+M9acQekBljUutZPrR5VK /tRFzOUIaCdJ7OB2kvmDVnobXyO/o4CEFZxrjiZy81ygR3Um7pPABSw9mdumT2oFyuZ3 HnaYjTCBltVuFAEfRPid5ouDrVAAGS21Htz0f94ubTajfhvdGGz0X+OwZZAqnUDxnHxx Xy0vP+P2YZfMqXiDfyQn3MKjw13NY1VUVlPD5zTJJDpBVxZzOXBbfjXRJMAHbAQ2zckE v1nw== X-Gm-Message-State: AOAM531SfWFEcRiLoxKIzFh87cX3ileLzNmNUpGK1FJqM5J7qsVaXH7T y75XcGIrhZ/bBWnFAXiGgeIe0LmSK6A= X-Google-Smtp-Source: ABdhPJz+9BmHtQI8cUyvCTsGOQp84h+ZnLiNKL2ptRyynE9Mt1JOqNtFxJW88DbQxBe4B1WJPiR5Xg== X-Received: by 2002:a17:902:820f:b0:148:f159:4b6d with SMTP id x15-20020a170902820f00b00148f1594b6dmr1326618pln.68.1640057113880; Mon, 20 Dec 2021 19:25:13 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id y4sm21808382pfi.178.2021.12.20.19.25.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Dec 2021 19:25:13 -0800 (PST) Received: from gnu-tgl-2.localdomain (gnu-tgl-2 [192.168.1.42]) by gnu-tgl-3.localdomain (Postfix) with ESMTPS id 3FA7FC0617 for ; Mon, 20 Dec 2021 19:25:12 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id E63C53003DA for ; Mon, 20 Dec 2021 19:16:16 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v3 1/2] elf: Properly align all PT_LOAD segments [BZ #28676] Date: Mon, 20 Dec 2021 19:16:15 -0800 Message-Id: <20211221031616.1534709-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 X-Spam-Status: No, score=-3029.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, 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 address --- elf/dl-load.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 From patchwork Tue Dec 21 03:16:16 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: 49133 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 B25203858025 for ; Tue, 21 Dec 2021 03:26:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B25203858025 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1640057178; bh=YCJQ5dO8cJXq525ck3cQYn191c0qolELsnclNMHe6YM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=IEtdfE/DXte1+eheqLFg9yN0bZaL1EvlL/vZgL6tbf9i51t/kWAW/FX7i6YTPs2Hu GiqoJGLgJYTmXdsSAVdhk3ma4OE8//4NjUkCG7GLlsuoomG794dJdivrlv+k8jrA43 NEIQRHrsIB+/KlkJRyRT0iVxXBsbLLFj2QCiyQmI= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by sourceware.org (Postfix) with ESMTPS id E78393858421 for ; Tue, 21 Dec 2021 03:25:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E78393858421 Received: by mail-pj1-x102d.google.com with SMTP id v16so11244076pjn.1 for ; Mon, 20 Dec 2021 19:25:14 -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:in-reply-to :references:mime-version:content-transfer-encoding; bh=YCJQ5dO8cJXq525ck3cQYn191c0qolELsnclNMHe6YM=; b=r/SPuqapv6zJMBR4e0i8xI21/WRjyzIQbxcM8j7gC7QKFafnRU8L0p16NvhW3YAtru 5UHQ9BaJpJipbPN+srr/nWcWw+/AHY+GFD+7F2wNwP+Yl9xmew5x0URBsw+wmIG/AW73 9AY40qZZXr5wFbM+mJtmfft5W6wvaKVaDZVsAZxK8mnOu6IYdwyumV7ff+5TW9pAd18Z /iOxqrlk08Rx/Jb/txUFAlgXoX4BgfEWJ4Y8GVNdQD3Lj2k88ajqfPY1usswRG57DSlK 3HDBG916k7ZjUc/ZaksLVHN0VyIsDu1Zx5FSwfSg+/JOx+uIBVkUMQoQ8DUarBG+unAh FApQ== X-Gm-Message-State: AOAM531rW2LRwqzWquN386avhTrMhIPkMkK5/lSpISh2zHsdJeByav3y QZv1rfiG4bFyeYeHZ/ZmzDrPQYewJMg= X-Google-Smtp-Source: ABdhPJyl1RqeNli8uF7suGr+5D3c6T7fQ8k7JG3N+SSd5UPDtCaJ4V1eTzam8aNQQdiIUDuwwe1jBw== X-Received: by 2002:a17:90b:1284:: with SMTP id fw4mr1482751pjb.45.1640057113748; Mon, 20 Dec 2021 19:25:13 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id 193sm6458350pfz.43.2021.12.20.19.25.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Dec 2021 19:25:13 -0800 (PST) Received: from gnu-tgl-2.localdomain (gnu-tgl-2 [192.168.1.42]) by gnu-tgl-3.localdomain (Postfix) with ESMTPS id 40966C0722 for ; Mon, 20 Dec 2021 19:25:12 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id E734A3003DB for ; Mon, 20 Dec 2021 19:16:16 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH v3 2/2] elf: Add a test for PT_LOAD segments with mixed p_align Date: Mon, 20 Dec 2021 19:16:16 -0800 Message-Id: <20211221031616.1534709-2-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211221031616.1534709-1-hjl.tools@gmail.com> References: <20211221031616.1534709-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3029.1 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" Add tst-alignmod3-edit to edit the copy of tst-alignmod3.so to lower p_align of the first PT_LOAD segment and verify that the shared library is mapped with the maximum p_align of all PT_LOAD segments. --- elf/Makefile | 18 ++++++ elf/tst-alignmod3-edit.c | 122 +++++++++++++++++++++++++++++++++++++++ elf/tst-p_align1.c | 27 +++++++++ 3 files changed, 167 insertions(+) create mode 100644 elf/tst-alignmod3-edit.c create mode 100644 elf/tst-p_align1.c diff --git a/elf/Makefile b/elf/Makefile index fe42caeb0e..c3402c65b2 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -378,6 +378,13 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod18 \ tst-audit18mod \ +ifeq (yesyes,$(build-shared)$(run-built-tests)) +tests += \ + tst-alignmod3-edit \ + tst-p_align1 \ + +endif + # Most modules build with _ISOMAC defined, but those filtered out # depend on internal headers. modules-names-tests = $(filter-out ifuncmod% tst-tlsmod%,\ @@ -1995,3 +2002,14 @@ $(objpfx)tst-ro-dynamic-mod.so: $(objpfx)tst-ro-dynamic-mod.os \ $(objpfx)tst-ro-dynamic-mod.os $(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig + +$(objpfx)tst-p_align1: $(objpfx)tst-p_alignmod1.so + +# Make a copy of tst-alignmod3.so and lower p_align of the first PT_LOAD +# segment. +$(objpfx)tst-p_alignmod1.so: $(objpfx)tst-alignmod3-edit \ + $(objpfx)tst-alignmod3.so + rm -f $@ + cp $(objpfx)tst-alignmod3.so $@ + $(test-wrapper-env) $(run-program-env) $(rtld-prefix) \ + $(objpfx)tst-alignmod3-edit $@ diff --git a/elf/tst-alignmod3-edit.c b/elf/tst-alignmod3-edit.c new file mode 100644 index 0000000000..7b7eafbeec --- /dev/null +++ b/elf/tst-alignmod3-edit.c @@ -0,0 +1,122 @@ +/* Lower p_align of the first PT_LOAD segment. + 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 + . */ + +#include +#include +#include +#include +#include +#include + +int +main (int argc, char ** argv) +{ + if (argc != 2) + { + printf ("Usage: %s: file\n", argv[0]); + return 0; + } + + const char *file_name = argv[1]; + ElfW(Ehdr) ehdr; + struct stat statbuf; + int errno_saved; + + if (stat (file_name, &statbuf) < 0) + error (1, errno, "%s: not exist \n", file_name); + + if (statbuf.st_size < sizeof (ehdr)) + error (1, 0, "%s: too small\n", file_name); + + FILE *file = fopen (file_name, "r+b"); + if (file == NULL) + error (1, 0, "%s: cann't open\n", file_name); + + /* Read in the identity array. */ + if (fread (&ehdr, sizeof (ehdr), 1, file) != 1) + { + errno_saved = errno; + fclose (file); + error (1, errno_saved, + "%s: can't read in ELF header\n", file_name); + } + + if (ehdr.e_ident[EI_MAG0] != ELFMAG0 + || ehdr.e_ident[EI_MAG1] != ELFMAG1 + || ehdr.e_ident[EI_MAG2] != ELFMAG2 + || ehdr.e_ident[EI_MAG3] != ELFMAG3) + { + fclose (file); + error (1, 0, "%s: bad ELF header\n", file_name); + } + + if (ehdr.e_type != ET_DYN) + { + fclose (file); + error (1, 0, "%s: not shared library\n", file_name); + } + + /* We only support 32 bit and 64 bit ELF files. */ + switch (ehdr.e_ident[EI_CLASS]) + { + default: + fclose (file); + error (1, 0, "%s: unsupported ELF class: %d\n", + file_name, ehdr.e_ident[EI_CLASS]); + break; + + case ELFCLASS32: + case ELFCLASS64: + break; + } + + size_t phdr_size = sizeof (ElfW(Phdr)) * ehdr.e_phentsize; + if (statbuf.st_size < (ehdr.e_phoff + phdr_size)) + { + fclose (file); + error (1, 0, "%s: too small\n", file_name); + } + + /* Map in ELF program header table. */ + void *base = mmap (NULL, ehdr.e_phoff + phdr_size, + PROT_READ | PROT_WRITE, MAP_SHARED, + fileno (file), 0); + if (base == MAP_FAILED) + { + errno_saved = errno; + fclose (file); + error (1, errno_saved, + "%s: failed to map in program header table\n", + file_name); + } + + ElfW(Phdr) *phdr = (ElfW(Phdr) *) (base + ehdr.e_phoff); + + for (int i = 0; i < ehdr.e_phnum; i++, phdr++) + if (phdr->p_type == PT_LOAD) + { + /* Reduce p_align of the first PT_LOAD segment by half. */ + phdr->p_align = phdr->p_align >> 1; + break; + } + + fclose (file); + munmap (base, phdr_size); + + return 0; +} diff --git a/elf/tst-p_align1.c b/elf/tst-p_align1.c new file mode 100644 index 0000000000..cab9793220 --- /dev/null +++ b/elf/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