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: 13658963 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB34B12AAF6 for ; Wed, 8 May 2024 17:31:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715189514; cv=none; b=WAnMVVturSRGVrV30yb3LNoUm8f81DjhpIq7NfSzwzn2RhBbMx+35ckv4kFa7aqp+rdwlTm4iFZyMxfUCMEtx5z8MJ6djolAL9v1IhJQS/YZtmyu2YNBP67KWWgTOEeC75kRwHZdx+TCV6rBy6Y2JxiTxGD1Rh4RQWlsBVkfadU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715189514; c=relaxed/simple; bh=EVV19YgGbcPQsIHd5yk4GzGYcoILxXyLnNlnQWFy9pw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QQ9NtBtd6QOwE3UqHDAl/B45TgKPGD976v+BE4q1WA5IOTL3yhsbHZCmni8FDQT1c7kG3OkFDaQ4bsz+x+pxb7yKs9SfREbFxghpWjIEI5rJ8O4LFRxrn5n0M8a6AfxQepOyVSMhm/W/fM+AB9DG0kA5E3hHSXr/0MnNBRyHZ00= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=TT823LaE; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="TT823LaE" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-1ee38966529so8246325ad.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=vger.kernel.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=TT823LaE2Z4LKXmY/o6l28b988iFT0/bsSW5L6lXPIOXs/YULCFcGE3WfOd071tshz kwNyO5Ka+V6+hZiZiUCej4/w3UtP2G4qpnQwPuMSgdQ89kc3bIbDsWPj83n13VDzCet5 bE2oTZmpkBrcIvXz3Bj4KvQ2xdfJfbDgp8B28= 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=nzfmNabx05eckUfmXVAtPj34xTgsKNhc5J9/eew0ObLhuFDOKo10BJOwaVU0iA/HkS O4II2roP+QWebme/ewR7UBGVdA6Lu6orSEBS9gNYLce2TiVy0YBCzt5zXUaOujJbPZQ7 EnPw8onJamGauE8nflyT1Ya9iGGO5+k5Ff7g9R1xn/w68QsvRnVPoSEm+XSd0DLzfQeg K4eoUffgOSaE1TFaWHpnaPwVA2bGCg3RvFPahhayToscuFKu3c56vMs1vRQvs8fgqcEQ M2t2B+J5knObglQPYtU+SinnDZdMmrFz7uu9cXtGq/cw7Pkj4Zyx+58Kr4nBmzjJ6jxc Cbcw== X-Forwarded-Encrypted: i=1; AJvYcCULOJyoDBazM0Dc/5JTR2HQslBgVc5TZi4pOMuUV0FNaUlONDCkYdsiMWqPMKVtuJbA6IgTkivfdaq1Q1f3CygphN60tObh/XgSOop028RA X-Gm-Message-State: AOJu0Yz8tn549H/WSyr6+i8vr4CgNQUlpIthHZrLVfv6NCRvfT8XmPPB 6V64YM145GCrAn9EHgPYt8iCOxi+g2onnWrVZ8QJD79zjZuCHz3TyxBM38K+LA== 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> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: 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 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(); } From patchwork Wed May 8 17:31:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 13658965 Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 52438127E34 for ; Wed, 8 May 2024 17:31:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715189516; cv=none; b=MmW+KhN0qFHqP/BYkdwrkjQskkf43+1c2r5cNu7HAaJZE4vOFI80cbB/S/UlPgkvZnt3cFYuTkyHHTA3rsSnNTLN9QG4XAvlAMQf7Rl7/JcKBUz23brZXV2UV4tqCac2lo8nK3foPI0wh3T1LDsw6g+S+ACUXhi9ZEFKIfmV/Lo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715189516; c=relaxed/simple; bh=Lh9sl0zFqUcR9HG/AVuIcrH791BNMQBsy4Th3x5GAR4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TGOfesXPS1tg3SOT64+O+TXZa4EphLtCEzw/QrzHRQafZ9mOJ79zZtLr1IEyCkGbjX1Pbh7YeeV+XI5sfHWVoXV+d0I1dqa8sNIYXPR019XhT+jWePqWT+sw0DmzG2QG/cGYuHMqHgau5Zub6bWsrz52rmeewfPGvKTpwbW38xE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=MACZdoTV; arc=none smtp.client-ip=209.85.210.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="MACZdoTV" Received: by mail-pf1-f174.google.com with SMTP id d2e1a72fcca58-6f44dd41a5cso51861b3a.0 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=vger.kernel.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=H2nNbu4XucHn8QDJu07t5inyAacTBVLvFhCSSSJI5uA=; b=MACZdoTV2HUHmjzFIxVNITkDEIP/reg4vX76Uhvb9lBuevHVple9BEfpKtirjINHfC ozLFMsRvQOAwTeoTC7r7kQvLG3E1WmVmFQb7swbvC5hjfus9Ext9ybjvqwYi7HDw3UO9 LmF4A2l++QQ3D8CU72PDo1PylWW8adWkSEpIM= 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=H2nNbu4XucHn8QDJu07t5inyAacTBVLvFhCSSSJI5uA=; b=hQu3VBchANA0wYaZZq8aBY1MNpLDdzV2P3DbiYnqDjHs7u+Jzvv4olhwBhYXA+U4+z Y7uTtjtw9jxfYg/SluNU4iyLWgNIWBzCbJm8oGIjc4/FaXHHFxv/txGN0SVATuomhnZJ jl33YvD1uMc3qv/P6q7WDz+0vb6ei9BZhCc82GaYg7yRJiKjbIoDTAHFfkhkRvpJJTkh TAAOt6S2ps/+O0IHsoBDDfgxq16ahV+SNzQ81gJI1stOg8lTBEmosX+NYD3xcEZWgXR7 1TRQb80sdaMTncuSsDDGiRvRD4B9aO7rMaUEMUZ62AOOun+VAXCEAhfa2qrj9mdZIZH6 SDjQ== X-Forwarded-Encrypted: i=1; AJvYcCV7BS5nR16g37K7198Gmpdl8J43+GTp0d/aTlHVDuqc0hLrXsBqW1mEknV9y/y9id5op3oZIYGyHyt+MpGmhZr2UYg2UH2yTj4r42kEWEvd X-Gm-Message-State: AOJu0Yyvl68khUVit1WDfDLJsQXKw7nPtvxc+nyL3F9gTmK/yIFirQca 0sV4cMAI0O7WnAjOQd5/dkeVNfRqTGsDLd2dXC0O0e3n7dHAXIRLg1E4IHruDw== X-Google-Smtp-Source: AGHT+IHhC2MOnPhfcqxPojENxgcZ8XwUYRxVGdudDH8TMRtD2+Tt4ejx6OP4QShOQ0NN1c/LqX7HRQ== X-Received: by 2002:a05:6a00:21d0:b0:6ec:f28b:659f with SMTP id d2e1a72fcca58-6f49c207395mr4060894b3a.3.1715189510677; 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 e18-20020a656492000000b006089cf2cde5sm10277706pgv.26.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 , Mike Rapoport , Rui Salvaterra , Victor Stinner , Jan Palus , Al Viro , Christian Brauner , Jan Kara , linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH 2/3] binfmt_elf: Calculate total_size earlier Date: Wed, 8 May 2024 10:31:47 -0700 Message-Id: <20240508173149.677910-2-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> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3041; i=keescook@chromium.org; h=from:subject; bh=Lh9sl0zFqUcR9HG/AVuIcrH791BNMQBsy4Th3x5GAR4=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBmO7cEHn0buAr/C675Nd09yTzC5UND2JGNtAzn6 7fAhDpYVyGJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCZju3BAAKCRCJcvTf3G3A JpCtD/9LYmlihZG7ywOzTinHJzY1kGMdJPl8aorBC0w8BZYWZG2L5735ch2DLxaqLeucHcOdIzd j2P5KQxKEFi3VSlTEJgG/CHFTE/LdNWf8K4HNiSgIPRvftdZy0yfsLhEg6c1Bc5+jOOGN7Yw1Oz 6PcT0O2RfYEkFZSrUDCPgVVNxk1+jVVG6NCQXKg/g1beIDLLZRXDt/CujNa4YHVUpd/PYIZvsBI tyyKrW1A2QVx0+ktTAviklFaU/7UJYQBntwA7dredHuOtT/fqjgzVNTigROk/o3oX6LwbM3R/nS rpbycTLj73Gn4W97wBLGOx8O9yk/tSZARqYHaJgCzAFLUSp6KzKoPZby1r7csVaek1B3X8fP+8+ BkY4XLEZdalGU8cLbxI+PY/Qr9tF2wa2MjCxf53MHCqPc76J9sF8E993yLTDuBhej9jyYD3tQ8f szKoB0M+V2j30jykwU46I56obv/BNssOUb7HZuY3opJ8Mjr05I2VVwIQkqlyrX5+S5i6mvqRIui +CwG4y1jlqtzUR5IZywuhfiJ1adpU8sxNVbg6dRC8xSQ5BOBZyf262o/4gaFHzFjKf5iPULmnZ1 SvfgCjHzQ3eQ8HeL0WrvMnveAWiwczVNHiEsljH0SLouDc9W4fSSSyePhi6mu7GKCpxPtjxXxWH YPVMgoHtsFF9p3A== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 In preparation to support PT_LOAD with large p_align values on non-PT_INTERP ET_DYN executables (i.e. "static pie"), we'll need to use the total_size details earlier. Move this separately now to make the next patch more readable. As total_size and load_bias are currently calculated separately, this has no behavioral impact. Signed-off-by: Kees Cook --- fs/binfmt_elf.c | 52 +++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 5397b552fbeb..56432e019d4e 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1061,7 +1061,34 @@ static int load_elf_binary(struct linux_binprm *bprm) * Header for ET_DYN binaries to calculate the * randomization (load_bias) for all the LOAD * Program Headers. + */ + + /* + * Calculate the entire size of the ELF mapping + * (total_size), used for the initial mapping, + * due to load_addr_set which is set to true later + * once the initial mapping is performed. + * + * Note that this is only sensible when the LOAD + * segments are contiguous (or overlapping). If + * used for LOADs that are far apart, this would + * cause the holes between LOADs to be mapped, + * running the risk of having the mapping fail, + * as it would be larger than the ELF file itself. * + * As a result, only ET_DYN does this, since + * some ET_EXEC (e.g. ia64) may have large virtual + * memory holes between LOADs. + * + */ + total_size = total_mapping_size(elf_phdata, + elf_ex->e_phnum); + if (!total_size) { + retval = -EINVAL; + goto out_free_dentry; + } + + /* * There are effectively two types of ET_DYN * binaries: programs (i.e. PIE: ET_DYN with INTERP) * and loaders (ET_DYN without INTERP, since they @@ -1102,31 +1129,6 @@ static int load_elf_binary(struct linux_binprm *bprm) * is then page aligned. */ load_bias = ELF_PAGESTART(load_bias - vaddr); - - /* - * Calculate the entire size of the ELF mapping - * (total_size), used for the initial mapping, - * due to load_addr_set which is set to true later - * once the initial mapping is performed. - * - * Note that this is only sensible when the LOAD - * segments are contiguous (or overlapping). If - * used for LOADs that are far apart, this would - * cause the holes between LOADs to be mapped, - * running the risk of having the mapping fail, - * as it would be larger than the ELF file itself. - * - * As a result, only ET_DYN does this, since - * some ET_EXEC (e.g. ia64) may have large virtual - * memory holes between LOADs. - * - */ - total_size = total_mapping_size(elf_phdata, - elf_ex->e_phnum); - if (!total_size) { - retval = -EINVAL; - goto out_free_dentry; - } } error = elf_load(bprm->file, load_bias + vaddr, elf_ppnt, From patchwork Wed May 8 17:31:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 13658966 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9092C12B158 for ; Wed, 8 May 2024 17:31:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715189516; cv=none; b=DM13lLXVV+0ZeTbwYZzImvuKvJYfT0Tvk+8hRXoV/n8Eq4miRd7LZ070MamhyZqc4PTWFF968wSqdjUIW+46z49lCPPUr6yBqLGdTAiP7KJ0fDJ0LiJkO6gkdrtCAZPQisDKEFyodapeVHaWq+cEB6ZAxzpgdLnQzJJTM14wWes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715189516; c=relaxed/simple; bh=eUy8l4dx1nlgASZnAXri0kDxbx6zhnXlB+I6YzLFjTw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qrekDvGc1PZGEcbsLa2lXwZ8ytdvETAYTUWaZRfia7Gesu9F8BBr7zVOnBneywCaGnUBFOwQ6SQvsYJ8yOzsIz4B0mobpzAgNxCyPNsBEXBkoWcErYA0/NGfkev1lkg6bYSkuvdIM8DAoJkLQQzeJwoJaCojTikwb3DAASZNRa0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=IwMJg9F9; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="IwMJg9F9" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-1ed835f3c3cso42205125ad.3 for ; Wed, 08 May 2024 10:31:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1715189512; x=1715794312; darn=vger.kernel.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=4rcMwpi5swukR9fu2rr+tgqRl98owlkzS7lAQiTyYR0=; b=IwMJg9F9lQfEe+AzV5jXn9VE/b5xqYgCuZThGRFk87TXfYrsFkqugIBbidix+EdaPm Wtua8BqjGwxslnquNHT2gXwsd/PUTcLhRmZIi52Ax8Wa2KSp2tR02ZvfQDPpV6m7oeIt KCkRtVeZjbZsbsiROw33eBmmRddR5m6kMa5k0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715189512; x=1715794312; 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=4rcMwpi5swukR9fu2rr+tgqRl98owlkzS7lAQiTyYR0=; b=tuG4Iyj0ONw18h5P8FuJf7NDATjj99BckoJniVWMHRNMYfG9vnDJn9itYH4Wl+jDe1 2mqJubWDyTaXnbHleHmUkwS8iR9mRbPUmXQqM/Z5BDTeFqRFv9Trb7ElOusEUhEFg+Kn 9scqhHEGSF3e9K6PdhC5zgoE0cGeAyIEJcaK0iBSyLJEFXnz9Bm3eN96gX4+kAfbWX+5 +A2Qw6VB0u8ImuFAwsK5fmxcjXXWi1joc6qHlEchd8s3GVKYgqyQKRxSL/j847NyLHJH 1jyGQr2TMtkOZBp1btI+RbRe9+wHAIc15S09vuXoPpwVVcclF/ZAmWDdZK5SQCJTLevi Hgpg== X-Forwarded-Encrypted: i=1; AJvYcCX3M/zCJS4qNh1YDybfWuo1eMBh32cTe/6Ja2iLU5gAEX/S2QPqiVN85dWveCRMu+xOY6DBgB9wvjSpg/1gDaC1yO5rKtBVQzz8d8tu7mzH X-Gm-Message-State: AOJu0YyZHtkEaFfm5VkFodFEBcXztz+QjGw843LlhjzlrQCVIBA2ssyu U0byoTRivaWPk1KQGPZTD7OdyfJR4KL8bpwIc0kZNlswk9YDVepicKI7LFPUgw== X-Google-Smtp-Source: AGHT+IFNr+b2pAfQcWXsO87OnrvROJLzoQf+GfNtUyLNTbuK3rS25oOgdGVm7lFzQQasZ1Pfzw4/2A== X-Received: by 2002:a17:902:6506:b0:1e6:766c:6a26 with SMTP id d9443c01a7336-1eeb017cfd1mr35094695ad.12.1715189512601; Wed, 08 May 2024 10:31:52 -0700 (PDT) Received: from www.outflux.net ([198.0.35.241]) by smtp.gmail.com with ESMTPSA id la13-20020a170902fa0d00b001ec412676adsm12094121plb.275.2024.05.08.10.31.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 May 2024 10:31:52 -0700 (PDT) From: Kees Cook To: "H . J . Lu" Cc: Kees Cook , Mike Rapoport , Rui Salvaterra , Victor Stinner , Jan Palus , Alexander Viro , Christian Brauner , Jan Kara , Eric Biederman , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, Chris Kennelly , Shuah Khan , Muhammad Usama Anjum , John Hubbard , Fangrui Song , Andrew Morton , Yang Yingliang , Mike Rapoport , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH 3/3] binfmt_elf: Honor PT_LOAD alignment for static PIE Date: Wed, 8 May 2024 10:31:48 -0700 Message-Id: <20240508173149.677910-3-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> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5293; i=keescook@chromium.org; h=from:subject; bh=eUy8l4dx1nlgASZnAXri0kDxbx6zhnXlB+I6YzLFjTw=; b=owEBbQKS/ZANAwAKAYly9N/cbcAmAcsmYgBmO7cEJD8sdRg2kTQVgy9QHVOS08welrL7Y9Xmg lC0fTmRrBSJAjMEAAEKAB0WIQSlw/aPIp3WD3I+bhOJcvTf3G3AJgUCZju3BAAKCRCJcvTf3G3A JtM8EACdAwapwoIf1FEL7K12lEwr6cSDnpSo/80JcopA9tWkFKXsiep6tWvoxZDOzJ1vc9e6b4V YLAAZBeXNl/xk6VrycAfh+xwdHN2k+KNbWvuJiD34NZowKV8tHkpCLzfyBMxlsEnwkpvxp4gaSj d4IhlEOcmwxk6K5OT+QsSmcjMCjEBIVRIK0goPl4GHq8aOi+sRueJ8TaFrjvw1+8mrbvG2DdFCe Uv8kWkvlo/ILaWPFZ0NusPLLdDhExA73NKe/ve4YZAfk0p6FRzmyWuHOaT7dkEYmU9yuB2JtgFA K2DJetC6ue7f0Q13jS3/JzqgB2vtfz+FNYDwsf5pZqI/0ziFNMCvidOe43tE7Iw0Lmdt2/BgPNL r8gTuz9/tlA2bbDc3e/kRUhuX5nwaHcjR/r8IVSalFQmyqc5IPAk37VHvGDmg6DIbep/8qnwvCF QLG5UBoysuC4MgK+oc4o06z7rfYgL2DuXeo2iJifxHJslw72FqLeVf4SKpDzrWKHhqNWvN5fVlO iCNqiQqRpRch+qbtKbcDu6uw3gg9q5q8qzx+EEXIHGhqVyKXRZKdXgMmXXp/my+9/udZV/cFPHl Axrb6nLzkWUCWdMUTIN4aZHCt5ihat6gagmdxw0UNkomFQUeEHsgPbhNUGZztz5L0i7eTM6zPj0 PxL8C6OI/h070mg== X-Developer-Key: i=keescook@chromium.org; a=openpgp; fpr=A5C3F68F229DD60F723E6E138972F4DFDC6DC026 The p_align values in PT_LOAD were ignored for static PIE executables (i.e. ET_DYN without PT_INTERP). This is because there is no way to request a non-fixed mmap region with a specific alignment. ET_DYN with PT_INTERP uses a separate base address (ELF_ET_DYN_BASE) and binfmt_elf performs the ASLR itself, which means it can also apply alignment. For the mmap region, the address selection happens deep within the vm_mmap() implementation (when the requested address is 0). The earlier attempt to implement this: commit 9630f0d60fec ("fs/binfmt_elf: use PT_LOAD p_align values for static PIE") commit 925346c129da ("fs/binfmt_elf: fix PT_LOAD p_align values for loaders") did not take into account the different base address origins, and were eventually reverted: aeb7923733d1 ("revert "fs/binfmt_elf: use PT_LOAD p_align values for static PIE"") In order to get the correct alignment from an mmap base, binfmt_elf must perform a 0-address load first, then tear down the mapping and perform alignment on the resulting address. Since this is slightly more overhead, only do this when it is needed (i.e. the alignment is not the default ELF alignment). This does, however, have the benefit of being able to use MAP_FIXED_NOREPLACE, to avoid potential collisions. With this fixed, enable the static PIE self tests again. Reported-by: H.J. Lu Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215275 Signed-off-by: Kees Cook --- Cc: H.J. Lu Cc: Mike Rapoport Cc: Rui Salvaterra Cc: Victor Stinner Cc: Jan Palus Cc: Alexander Viro Cc: Christian Brauner Cc: Jan Kara Cc: Eric Biederman Cc: linux-fsdevel@vger.kernel.org Cc: linux-mm@kvack.org --- fs/binfmt_elf.c | 42 +++++++++++++++++++++++---- tools/testing/selftests/exec/Makefile | 2 +- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 56432e019d4e..cbb07a9c02d4 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1088,10 +1088,13 @@ static int load_elf_binary(struct linux_binprm *bprm) goto out_free_dentry; } + /* Calculate any requested alignment. */ + alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum); + /* * There are effectively two types of ET_DYN - * binaries: programs (i.e. PIE: ET_DYN with INTERP) - * and loaders (ET_DYN without INTERP, since they + * binaries: programs (i.e. PIE: ET_DYN with PT_INTERP) + * and loaders (ET_DYN without PT_INTERP, since they * _are_ the ELF interpreter). The loaders must * be loaded away from programs since the program * may otherwise collide with the loader (especially @@ -1111,15 +1114,44 @@ static int load_elf_binary(struct linux_binprm *bprm) * without MAP_FIXED nor MAP_FIXED_NOREPLACE). */ if (interpreter) { + /* On ET_DYN with PT_INTERP, we do the ASLR. */ load_bias = ELF_ET_DYN_BASE; if (current->flags & PF_RANDOMIZE) load_bias += arch_mmap_rnd(); - alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum); + /* Adjust alignment as requested. */ if (alignment) load_bias &= ~(alignment - 1); elf_flags |= MAP_FIXED_NOREPLACE; - } else - load_bias = 0; + } else { + /* + * For ET_DYN without PT_INTERP, we rely on + * the architectures's (potentially ASLR) mmap + * base address (via a load_bias of 0). + * + * When a large alignment is requested, we + * must do the allocation at address "0" right + * now to discover where things will load so + * that we can adjust the resulting alignment. + * In this case (load_bias != 0), we can use + * MAP_FIXED_NOREPLACE to make sure the mapping + * doesn't collide with anything. + */ + if (alignment > ELF_MIN_ALIGN) { + load_bias = elf_load(bprm->file, 0, elf_ppnt, + elf_prot, elf_flags, total_size); + if (BAD_ADDR(load_bias)) { + retval = IS_ERR_VALUE(load_bias) ? + PTR_ERR((void*)load_bias) : -EINVAL; + goto out_free_dentry; + } + vm_munmap(load_bias, total_size); + /* Adjust alignment as requested. */ + if (alignment) + load_bias &= ~(alignment - 1); + elf_flags |= MAP_FIXED_NOREPLACE; + } else + load_bias = 0; + } /* * Since load_bias is used for all subsequent loading diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index 619cff81d796..ab67d58cfab7 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile @@ -6,7 +6,7 @@ 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) +ALIGNMENT_TESTS := $(ALIGN_PIES) $(ALIGN_STATIC_PIES) TEST_PROGS := binfmt_script.py TEST_GEN_PROGS := execveat non-regular $(ALIGNMENT_TESTS)