From patchwork Mon Mar 7 09:18:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 12771453 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 46D4BC43217 for ; Mon, 7 Mar 2022 09:51:01 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 59F9B8D0002; Mon, 7 Mar 2022 04:51:00 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 5292C8D0001; Mon, 7 Mar 2022 04:51:00 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 4170C8D0002; Mon, 7 Mar 2022 04:51:00 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (relay.hostedemail.com [64.99.140.28]) by kanga.kvack.org (Postfix) with ESMTP id 2C4E68D0001 for ; Mon, 7 Mar 2022 04:51:00 -0500 (EST) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay12.hostedemail.com (Postfix) with ESMTP id 030DF12121A for ; Mon, 7 Mar 2022 09:50:59 +0000 (UTC) X-FDA: 79217121480.03.50C41D5 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by imf13.hostedemail.com (Postfix) with ESMTP id 7103C20009 for ; Mon, 7 Mar 2022 09:50:59 +0000 (UTC) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A6268B810B2; Mon, 7 Mar 2022 09:50:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B9591C340F3; Mon, 7 Mar 2022 09:50:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1646646657; bh=J+/jw8k4zKjtveZbhrOnbT76RkWaWlpLCcmkq5W6CFc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zjc2i/SWH0wbuuFD9OcsMlC0QzHhvoBqv8F9p+yx7mlvaSVmRNrDWHVSIuC0iaYEZ eZp4CpWP1MzW/vMIKjDaLahPT+oeD/yWOiwXUBegWqD/YYdEcigTNcm1K4aCEITM0I TSQAuUsOKAOrhILvL0pp/xykKU/tvOxXrUZLJmSg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Biederman , Alexander Viro , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, matoro , matoro , John Paul Adrian Glaubitz , Kees Cook Subject: [PATCH 5.16 050/186] binfmt_elf: Avoid total_mapping_size for ET_EXEC Date: Mon, 7 Mar 2022 10:18:08 +0100 Message-Id: <20220307091655.493807730@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220307091654.092878898@linuxfoundation.org> References: <20220307091654.092878898@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 7103C20009 X-Stat-Signature: 789h49ceyh8fk3b114xs6n6hkcw9oksq Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=linuxfoundation.org header.s=korg header.b="zjc2i/SW"; spf=pass (imf13.hostedemail.com: domain of gregkh@linuxfoundation.org designates 145.40.68.75 as permitted sender) smtp.mailfrom=gregkh@linuxfoundation.org; dmarc=pass (policy=none) header.from=linuxfoundation.org X-HE-Tag: 1646646659-170283 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: From: Kees Cook commit 439a8468242b313486e69b8cc3b45ddcfa898fbf upstream. Partially revert commit 5f501d555653 ("binfmt_elf: reintroduce using MAP_FIXED_NOREPLACE"), which applied the ET_DYN "total_mapping_size" logic also to ET_EXEC. At least ia64 has ET_EXEC PT_LOAD segments that are not virtual-address contiguous (but _are_ file-offset contiguous). This would result in a giant mapping attempting to cover the entire span, including the virtual address range hole, and well beyond the size of the ELF file itself, causing the kernel to refuse to load it. For example: $ readelf -lW /usr/bin/gcc ... Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz ... ... LOAD 0x000000 0x4000000000000000 0x4000000000000000 0x00b5a0 0x00b5a0 ... LOAD 0x00b5a0 0x600000000000b5a0 0x600000000000b5a0 0x0005ac 0x000710 ... ... ^^^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^ File offset range : 0x000000-0x00bb4c 0x00bb4c bytes Virtual address range : 0x4000000000000000-0x600000000000bcb0 0x200000000000bcb0 bytes Remove the total_mapping_size logic for ET_EXEC, which reduces the ET_EXEC MAP_FIXED_NOREPLACE coverage to only the first PT_LOAD (better than nothing), and retains it for ET_DYN. Ironically, this is the reverse of the problem that originally caused problems with MAP_FIXED_NOREPLACE: overlapping PT_LOAD segments. Future work could restore full coverage if load_elf_binary() were to perform mappings in a separate phase from the loading (where it could resolve both overlaps and holes). Cc: Eric Biederman Cc: Alexander Viro Cc: linux-fsdevel@vger.kernel.org Cc: linux-mm@kvack.org Reported-by: matoro Fixes: 5f501d555653 ("binfmt_elf: reintroduce using MAP_FIXED_NOREPLACE") Link: https://lore.kernel.org/r/a3edd529-c42d-3b09-135c-7e98a15b150f@leemhuis.info Tested-by: matoro Link: https://lore.kernel.org/lkml/ce8af9c13bcea9230c7689f3c1e0e2cd@matoro.tk Tested-By: John Paul Adrian Glaubitz Link: https://lore.kernel.org/lkml/49182d0d-708b-4029-da5f-bc18603440a6@physik.fu-berlin.de Cc: stable@vger.kernel.org Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/binfmt_elf.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1135,14 +1135,25 @@ out_free_interp: * is then page aligned. */ load_bias = ELF_PAGESTART(load_bias - vaddr); - } - /* - * Calculate the entire size of the ELF mapping (total_size). - * (Note that load_addr_set is set to true later once the - * initial mapping is performed.) - */ - if (!load_addr_set) { + /* + * 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) {