From patchwork Wed May 8 17:31:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 13658953 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 52B53C19F4F for ; Wed, 8 May 2024 17:31:58 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E761D6B009A; Wed, 8 May 2024 13:31:55 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id DD8486B009E; Wed, 8 May 2024 13:31:55 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A0AD86B009A; Wed, 8 May 2024 13:31:55 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 6D1EF6B009B for ; Wed, 8 May 2024 13:31:55 -0400 (EDT) Received: from smtpin07.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 336FEA0C71 for ; Wed, 8 May 2024 17:31:55 +0000 (UTC) X-FDA: 82095921390.07.BA1DC36 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) by imf22.hostedemail.com (Postfix) with ESMTP id 2F53DC0018 for ; Wed, 8 May 2024 17:31:51 +0000 (UTC) Authentication-Results: imf22.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=L0Hnd5hC; spf=pass (imf22.hostedemail.com: domain of keescook@chromium.org designates 209.85.214.182 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (policy=none) header.from=chromium.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1715189512; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=ckhcb2/0RYF0Gnhe/jQlCjJECN0VZ08/Fvs6ZKfOACc=; b=aQm1EUlVORl0pTRoxAWiUhw58f0dzdafbyu+LyMIj3iOTJt7+Xg1JeAThXldDL028cx1Sj shxGTQsjLMRlddxY90o89dLoAKG15jrZWeJEKFn8oY6jgk3fJVPbu7sj90iBwGzCW8HNEd aC8IEZEWsqwm9v+QO3scIl9I124TItg= ARC-Authentication-Results: i=1; imf22.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=L0Hnd5hC; spf=pass (imf22.hostedemail.com: domain of keescook@chromium.org designates 209.85.214.182 as permitted sender) smtp.mailfrom=keescook@chromium.org; dmarc=pass (policy=none) header.from=chromium.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1715189512; a=rsa-sha256; cv=none; b=6Kw8xdL1GrESYsdPmgIEve1KmKt1OY7gOIlvJq4aFc+qeuEA1j4Wo+KDhp+znglZN5COZo KKs7AoOrSbx3Vq0rT5TBemvMVZYGDT3E5VqJ4K2MOEXS9hPfGOb8rVx7p8NYuI+Hj3xSL0 EG9c19m/gRyvm2kDphUlXAGHVEvP4dI= Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-1ee38966529so8246315ad.1 for ; Wed, 08 May 2024 10:31:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1715189511; x=1715794311; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ckhcb2/0RYF0Gnhe/jQlCjJECN0VZ08/Fvs6ZKfOACc=; b=L0Hnd5hCTjGbwH4xwPArEqyz5btXwvS7RsCaz6lXcV+C2zzHta+wrWMhBeiI0FJHsm QlS25wEDEKGlrSFN3YJ1Fs0SbmJ99LcGtgRAHI466UsJUP5E1O8eN0Wn/vPQ24VAACCU Obcb7A7tFCnJo6fJMZbN2cFDtKVC/+2MqhcbY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715189511; x=1715794311; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ckhcb2/0RYF0Gnhe/jQlCjJECN0VZ08/Fvs6ZKfOACc=; b=QDQ9p348e5apxdSfCfbui1tFbd1b+00GSyuNpReR8P/LWdLKheMmA0rnHI2ge+EoAG 07zdFXeuvhaTuWgticbdO/APjCSAqpyvnul8Sc0I69ee9oERGg2lOiaVMZDZykm0WVsZ kAs/bbcRXBmRx7Q6fwiUeTBkjOdHwwaGjTaj0+Sd1TtP8oQXuBEWsJbowGle0As/t+YG UEj9QS7zAhR19kb9QizRh5al6jGuLFqiEYdiu84ZJaM31ImAcmxFbV0/cF9IDD7EKDTw /ewBRY93nK+AttW9erZzw6Vf6gpuVJ0+4iftSl8kXc77sH1Oq842NfzI2j0oGQHat1zK o1vA== X-Forwarded-Encrypted: i=1; AJvYcCWoYrczpM3r0p+JTgTPOLuk+x6soZw53/xK0wF2A0Wo2NlNJfBHHEnb4+XUmeA3LfB58WDKmqb4jCyAQ2OHRbFo5Gk= X-Gm-Message-State: AOJu0YyPwIdRBmT5z7CyWRGrsa44uS0X8AMSWz4KRuLHVCzO4EIDVnaB z0RrOr5za1MQmFHlq7HUoeCFD9vv+JgXclCfDdq8jdXjBEojaIHdqupYl20BuA== X-Google-Smtp-Source: AGHT+IFe9RE0PlweeOYjLwef5REO+i00c2oo7HJiryhYfaXZtd4BvtB2nxrgXXbdGr6zE8h3r5g01g== X-Received: by 2002:a17:902:dacc:b0:1eb:8299:db35 with SMTP id d9443c01a7336-1eefa58cfe5mr4314535ad.32.1715189510956; Wed, 08 May 2024 10:31:50 -0700 (PDT) Received: from www.outflux.net ([198.0.35.241]) by smtp.gmail.com with ESMTPSA id b3-20020a170902d30300b001e2a479954dsm12129520plc.181.2024.05.08.10.31.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 May 2024 10:31:50 -0700 (PDT) From: Kees Cook To: "H . J . Lu" Cc: Kees Cook , Chris Kennelly , Eric Biederman , Shuah Khan , Muhammad Usama Anjum , John Hubbard , Fangrui Song , Andrew Morton , Yang Yingliang , linux-mm@kvack.org, linux-kselftest@vger.kernel.org, Mike Rapoport , Rui Salvaterra , Victor Stinner , Jan Palus , Al Viro , Christian Brauner , Jan Kara , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH 1/3] selftests/exec: Build both static and non-static load_address tests Date: Wed, 8 May 2024 10:31:46 -0700 Message-Id: <20240508173149.677910-1-keescook@chromium.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240508172848.work.131-kees@kernel.org> References: <20240508172848.work.131-kees@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6882; i=keescook@chromium.org; h=from:subject; bh=EVV19YgGbcPQsIHd5yk4GzGYcoILxXyLnNlnQWFy9pw=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBmO7cE7X4mhGALtYnO3LLjThfOhTf4zqWRzUonM YIEVDy8ECGJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCZju3BAAKCRCJcvTf3G3A JqzhEACugoYdfeBq9hllOhN230YzjegmLLmyhu7D4ZUW4opBdmlFfiuiuoZexZQUxlhuR0aHobi Xktw+k9RzRwGjeUQm6DqEFJ5/ypq1MYaS2e7qfeSwkLfsLSeRGnn2N3Ag6eXL/e/cXhkcQTPo9b Vfd0+o5ctjpzD9SDvJKtjz8hG69soCmtgK6rJyovDQslCzC7aDH33Fvri9GB9lyD1Miafv0AZEA 9H8+/ycD1h+4dKxrn5h5DP7ZMGEhcGDSz8BTtvTibEaIEJNsIVsPkfb0FySoNeRpgIlKOcynYKm W5rADoIiq2Js477XNNWD8awi1czVmZBgBP7vXuSdmgQki7LmPUyd3uBH+xc4wZJX7YqTzuU2p6f 0kCwpXgkwxz5lVtdItPdl4q7RHdCBAungFLFpCqNvhxfnOjp4EeOQcPZWWrBJ4VRM6JnLz6AyBi oaadMihDqXQ3DpElP4hIeED20RpP6RnOoxv9NQPTDNLVryc+aqXTTJyaNVDhjFGTZ3lDDrt2YQJ BJuugxHoIMXKzmxjqagdcHEkkEQc3QT+0a7jsiUyJoFqb18rRzPbTRz3p5f5pMt+fBN/tbQxnfY gKd6t/Mj+QNdLzLoBnE1r39sCfnDiklNPn3+eQskJ8fUaFsewNAWbhyjVVux6wK3OnQrrcooaNB Agj16aAcMuOgCnA== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 X-Stat-Signature: oanw4k3xj1hayu1o5baiuitcw5gy9c7m X-Rspam-User: X-Rspamd-Queue-Id: 2F53DC0018 X-Rspamd-Server: rspam05 X-HE-Tag: 1715189511-741271 X-HE-Meta: U2FsdGVkX1+nTqlZVuytgA9vMu+D674EjKxSMb7tQdEzVRxBmRGVi7xd1bs1/OP47raUoOXaUDHH4lxM0RD6kMh1n8rlAlbHhPmspk7RcC5tuaeWK37taHYyygi9/sCJuBIwOYCwypaCtXTr5WGVuqtT7Q1GSVWL0f8HaqBDSlnyxkkBmuyZICupnRnks/zQVxlO1gIU5yjaaNW39Te9oNuixYqXeX9neHz2eZB5dEwTx82u2XeeN4EaTLnziLGBInt6vBmowl/ayjiivmfli/UEgx6fNc3RnjngmEyamMrKMHVhqI+C98TlA7w3m6GeYTLZGkJT1N201Orh8Pa5gVlTzTHH5dooW0TJxvbm9pfKSSk50Yx9UXzQqPhpPcO1lF0CmaB5dqoai8WYYgGfQ5yaqIxqiLXUqyB8mdHfu8b0EaSGWrrmW+3TkZaJI1O33jIaVAzKyP/VOuGhenDhayJKDVQhpiRfMfZnRlPeK1MXsPkMRrsLhWzfjbWTzK3ramX6vXuTvApo5GjoBeefkwhLhQxo3bfKmtDsvkmw7tvCLTnbciZErPIXbaN7TdaJw/bVwEMfBzqo2C54w4IPs59iufxU4Op1bIxiqj7K3BYU3WV9GF76hDGARKz6n7J3t8mm1rQuOKKSx8eUC3ORgb6vZBMZzE/HiuI0IZyFZ8JJoEjmMAO6g2FGfcls92Hw+pi7Gb9oZbzNTQvY2AiVRTO+brLJxWa5+Egh78hKG+Pei8eNc/jpVMvLDesP0z7707I0k0/nFvS227sp/iH8nvdOnMmOpwF4t9UZVvavZ4zZbr5LePCUEyzcyZj3YFj/TWXb2f7JAb+APzNs++NaAmm/xSmWqK5A9wkF/zG8J/AqQMjf/9I86+vI1NgBICBzZPVBg9hazdwOLJ8YnlZeOQvQd073YB8DKsSVo4NlpWrmVHVDOWCmj5JBoPTEIPLI0nP9OxSocC9qSuo9YGP Z1lEC+f3 wg8Awj8L8Vx5Jjsp1zpDQokOmqDtJnm4heK1dXcxS2e7qYf6Z/eQkxNhRyERuIXC2GLwHLgwO79ZG9+78WqL5wGXu97OpxJEvsrASvdY1cursqKlRtqJAXtHck/aQ6+sRNBSppafuy9wJ06PdDu3fLyxuJ/R7HK3mh8uTJ54vMQV5b3pkZwmbw+8xgaLXXeX8a/UCLX7GDwyFXtA0ggizqTuex1wQRXwzDBSfwxDK0Bj803Rok/uVF3wxafO/jBE/00zQTeU+vfz1BjVoZF1zNoABxrzFWQw85xQ+bo+6mP2Bd5a9Rv+3GWI+zszgKlinYgbZdeD9beFpZyesPRLyiqJK79pX0la00zQ8I2T88KBdmlvZ3p/BqPSHOOlqFlGHSr8pi8zitSJ1X7mnWt2CENZy882mXK6kShjXBOghBuxLhrWdnnxpIMhOx6xFzQ+0hy3e9+09IqkzqKdJ+1MWHx5hXXoIcoxNS3/9h2Qcpcou/wh10jxRWfj/TeG7PmPg7kHpTh7DuQS2ocqLip266GFk7ZtwABRdzWbTovdes80YjXyGfIQ2N8HrWPCq6k6eXBZo/3epC75qPwlzWJcMpCl7Imfww3NZWOY028Ctqqq02wsNMAa0ymPC5rllsW87UyBXoxLU9CY4lvW//pDnr5oryWTsRHYOMc2a+o2OzNpI1R+Nl/uvulCqifbztW7eiGHl4yAmWe8SGLqXc+n1gOghHUHE5y5YPGSWua0Ox/hL03DGrkf4q/jXHGOK0H4KjQDG6BqvPsS8gVlItsp/J6mNWTQ5kA7RaS9fiYrAJ5GaeBsrxEtw0lwXoslF5CnLXyZURbG9pOIFIOXA3keFXS7Mthet4q0eoP3IZmQTuCW7NApZjuhm2exkNyFyQ34AlVVy X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: After commit 4d1cd3b2c5c1 ("tools/testing/selftests/exec: fix link error"), the load address alignment tests tried to build statically. This was silently ignored in some cases. However, after attempting to further fix the build by switching to "-static-pie", the test started failing. This appears to be due to non-PT_INTERP ET_DYN execs ("static PIE") not doing alignment correctly, which remains unfixed[1]. See commit aeb7923733d1 ("revert "fs/binfmt_elf: use PT_LOAD p_align values for static PIE"") for more details. Provide rules to build both static and non-static PIE binaries, improve debug reporting, and perform several test steps instead of a single all-or-nothing test. However, do not actually enable static-pie tests; alignment specification is only supported for ET_DYN with PT_INTERP ("regular PIE"). Link: https://bugzilla.kernel.org/show_bug.cgi?id=215275 [1] Signed-off-by: Kees Cook --- Cc: Chris Kennelly Cc: Eric Biederman Cc: Shuah Khan Cc: Muhammad Usama Anjum Cc: John Hubbard Cc: Fangrui Song Cc: Andrew Morton Cc: Yang Yingliang Cc: linux-mm@kvack.org Cc: linux-kselftest@vger.kernel.org --- tools/testing/selftests/exec/Makefile | 19 +++--- tools/testing/selftests/exec/load_address.c | 67 +++++++++++++++++---- 2 files changed, 66 insertions(+), 20 deletions(-) diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index fb4472ddffd8..619cff81d796 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile @@ -3,8 +3,13 @@ CFLAGS = -Wall CFLAGS += -Wno-nonnull CFLAGS += -D_GNU_SOURCE +ALIGNS := 0x1000 0x200000 0x1000000 +ALIGN_PIES := $(patsubst %,load_address.%,$(ALIGNS)) +ALIGN_STATIC_PIES := $(patsubst %,load_address.static.%,$(ALIGNS)) +ALIGNMENT_TESTS := $(ALIGN_PIES) + TEST_PROGS := binfmt_script.py -TEST_GEN_PROGS := execveat load_address_4096 load_address_2097152 load_address_16777216 non-regular +TEST_GEN_PROGS := execveat non-regular $(ALIGNMENT_TESTS) TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir # Makefile is a run-time dependency, since it's accessed by the execveat test TEST_FILES := Makefile @@ -28,9 +33,9 @@ $(OUTPUT)/execveat.symlink: $(OUTPUT)/execveat $(OUTPUT)/execveat.denatured: $(OUTPUT)/execveat cp $< $@ chmod -x $@ -$(OUTPUT)/load_address_4096: load_address.c - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=0x1000 -pie -static $< -o $@ -$(OUTPUT)/load_address_2097152: load_address.c - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=0x200000 -pie -static $< -o $@ -$(OUTPUT)/load_address_16777216: load_address.c - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=0x1000000 -pie -static $< -o $@ +$(OUTPUT)/load_address.0x%: load_address.c + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=$(lastword $(subst ., ,$@)) \ + -fPIE -pie $< -o $@ +$(OUTPUT)/load_address.static.0x%: load_address.c + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-z,max-page-size=$(lastword $(subst ., ,$@)) \ + -fPIE -static-pie $< -o $@ diff --git a/tools/testing/selftests/exec/load_address.c b/tools/testing/selftests/exec/load_address.c index 17e3207d34ae..8257fddba8c8 100644 --- a/tools/testing/selftests/exec/load_address.c +++ b/tools/testing/selftests/exec/load_address.c @@ -5,11 +5,13 @@ #include #include #include +#include #include "../kselftest.h" struct Statistics { unsigned long long load_address; unsigned long long alignment; + bool interp; }; int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) @@ -26,11 +28,20 @@ int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) stats->alignment = 0; for (i = 0; i < info->dlpi_phnum; i++) { + unsigned long long align; + + if (info->dlpi_phdr[i].p_type == PT_INTERP) { + stats->interp = true; + continue; + } + if (info->dlpi_phdr[i].p_type != PT_LOAD) continue; - if (info->dlpi_phdr[i].p_align > stats->alignment) - stats->alignment = info->dlpi_phdr[i].p_align; + align = info->dlpi_phdr[i].p_align; + + if (align > stats->alignment) + stats->alignment = align; } return 1; // Terminate dl_iterate_phdr. @@ -38,27 +49,57 @@ int ExtractStatistics(struct dl_phdr_info *info, size_t size, void *data) int main(int argc, char **argv) { - struct Statistics extracted; - unsigned long long misalign; + struct Statistics extracted = { }; + unsigned long long misalign, pow2; + bool interp_needed; + char buf[1024]; + FILE *maps; int ret; ksft_print_header(); - ksft_set_plan(1); + ksft_set_plan(4); + + /* Dump maps file for debugging reference. */ + maps = fopen("/proc/self/maps", "r"); + if (!maps) + ksft_exit_fail_msg("FAILED: /proc/self/maps: %s\n", strerror(errno)); + while (fgets(buf, sizeof(buf), maps)) { + ksft_print_msg("%s", buf); + } + fclose(maps); + /* Walk the program headers. */ ret = dl_iterate_phdr(ExtractStatistics, &extracted); if (ret != 1) ksft_exit_fail_msg("FAILED: dl_iterate_phdr\n"); - if (extracted.alignment == 0) - ksft_exit_fail_msg("FAILED: No alignment found\n"); - else if (extracted.alignment & (extracted.alignment - 1)) - ksft_exit_fail_msg("FAILED: Alignment is not a power of 2\n"); + /* Report our findings. */ + ksft_print_msg("load_address=%#llx alignment=%#llx\n", + extracted.load_address, extracted.alignment); + + /* If we're named with ".static." we expect no INTERP. */ + interp_needed = strstr(argv[0], ".static.") == NULL; + + /* Were we built as expected? */ + ksft_test_result(interp_needed == extracted.interp, + "%s INTERP program header %s\n", + interp_needed ? "Wanted" : "Unwanted", + extracted.interp ? "seen" : "missing"); + + /* Did we find an alignment? */ + ksft_test_result(extracted.alignment != 0, + "Alignment%s found\n", extracted.alignment ? "" : " NOT"); + + /* Is the alignment sane? */ + pow2 = extracted.alignment & (extracted.alignment - 1); + ksft_test_result(pow2 == 0, + "Alignment is%s a power of 2: %#llx\n", + pow2 == 0 ? "" : " NOT", extracted.alignment); + /* Is the load address aligned? */ misalign = extracted.load_address & (extracted.alignment - 1); - if (misalign) - ksft_exit_fail_msg("FAILED: alignment = %llu, load_address = %llu\n", - extracted.alignment, extracted.load_address); + ksft_test_result(misalign == 0, "Load Address is %saligned (%#llx)\n", + misalign ? "MIS" : "", misalign); - ksft_test_result_pass("Completed\n"); ksft_finished(); }