From patchwork Tue Jul 20 11:14:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 12388055 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.2 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94E5AC07E95 for ; Tue, 20 Jul 2021 11:17:02 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5B44260FDB for ; Tue, 20 Jul 2021 11:17:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5B44260FDB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Date:Cc:To:From:Subject: Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=czjz0jLL3iEW2P3smkwtQ25QK46g2MsBn2HYn3004ww=; b=j0hrCkV7S6RKYa 26rCULZXJ8cK2s5YgcRIzz6J7bGM4FPy9LtH3a1oZ7ggf0NETem+ktpH7nXGaz7rOexVeeLGgaihs 3lAZrk39Adp4pHSf9Dcumg9V/hsQGBkU5KNJZaQXOGN1yMYwIdfD1PXk1bXxHptcMn/9iVKsWPulJ 0J7teQgFkhPnTRC3oHCENCoCcPcF+07GSCqvw+0dXPwEMb5WYEw2pD4Avko/XHrpU30eJwOEEOceM vT6+FjX4JNWgRRJhKXuzAea5Sq0K8dQt2IgK60lKORKXQayftYeUyYsoRgTWRQBjSP3T49NzxQzGQ oWwyi0YcHObQLsW7G93Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1m5niW-00CcJT-Ne; Tue, 20 Jul 2021 11:15:16 +0000 Received: from gate.crashing.org ([63.228.1.57]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1m5niS-00CcIA-RV for linux-arm-kernel@lists.infradead.org; Tue, 20 Jul 2021 11:15:14 +0000 Received: from ip6-localhost (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id 16KBE5N6017585; Tue, 20 Jul 2021 06:14:06 -0500 Message-ID: Subject: [PATCH 1/2] arm64: efi: kaslr: Fix occasional random alloc (and boot) failure From: Benjamin Herrenschmidt To: linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , linux-efi@vger.kernel.org, "linux-kernel@vger.kernel.org Will Deacon" Date: Tue, 20 Jul 2021 21:14:05 +1000 User-Agent: Evolution 3.36.5-0ubuntu1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210720_041513_092564_43B0E912 X-CRM114-Status: GOOD ( 12.78 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The EFI stub random allocator used for kaslr on arm64 has a subtle bug. In function get_entry_num_slots() which counts the number of possible allocation "slots" for the image in a given chunk of free EFI memory, "last_slot" can become negative if the chunk is smaller than the requested allocation size. The test "if (first_slot > last_slot)" doesn't catch it because both first_slot and last_slot are unsigned. I chose not to make them signed to avoid problems if this is ever used on architectures where there are meaningful addresses with the top bit set. Instead, fix it with an additional test against the allocation size. This can cause a boot failure in addition to a loss of randomisation due to another bug in the arm64 stub fixed separately. Signed-off-by: Benjamin Herrenschmidt Fixes: 2ddbfc81eac8 (efi: stub: add implementation of efi_random_alloc()) Acked-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/randomalloc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c index a408df474d83..724155b9e10d 100644 --- a/drivers/firmware/efi/libstub/randomalloc.c +++ b/drivers/firmware/efi/libstub/randomalloc.c @@ -30,6 +30,8 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1, (u64)ULONG_MAX); + if (region_end < size) + return 0; first_slot = round_up(md->phys_addr, align); last_slot = round_down(region_end - size + 1, align); From patchwork Tue Jul 20 11:14:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 12388057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.2 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 945C7C07E95 for ; Tue, 20 Jul 2021 11:17:06 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5F2C46023D for ; Tue, 20 Jul 2021 11:17:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5F2C46023D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Date:Cc:To:From:Subject: Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=iE49IHWKAXRQsjcnx/PyU06V1E5piQ/CpAY7/PnotRM=; b=1nYDBTQt1vLWK2 SMe+1gt50srUGwgNUAiinw8z7StJsZOd5fKn7egd0EWgDWH+OtW08bgiMAzELZnoY/36NBsD1ZvJ7 09oBVkjYYDpcmAc5QpEhi4roJ2kVOEW5sANjQQTrnycIqIhXJxFE0whKG1H13/6qHM0fJR8ftodXg AUJM7iWOC891GT3gC5zpbt+o9OZyp4o6Brr4jalWAdACLnxAV/ToWjMGIpjDCV4H95iYCdfqi7aOr ZD33vv9zEOlYh5bquJ1/6Mkchx2R0ip3LD0PFgKXWUfWX2P8pRbg8EuiKI8lMBd8TD9ntDq9Y7u0m piIa0PBjptBxaTPl9izg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1m5nii-00CcNb-Sf; Tue, 20 Jul 2021 11:15:28 +0000 Received: from gate.crashing.org ([63.228.1.57]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1m5niW-00CcJn-BV for linux-arm-kernel@lists.infradead.org; Tue, 20 Jul 2021 11:15:17 +0000 Received: from ip6-localhost (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.14.1) with ESMTP id 16KBECBR017610; Tue, 20 Jul 2021 06:14:13 -0500 Message-ID: <161920fc31ec4168290ca31b3e4ac7a75ac1df6b.camel@kernel.crashing.org> Subject: [PATCH 2/2] arm64: efi: kaslr: Fix boot failure if efi_random_alloc() fails From: Benjamin Herrenschmidt To: linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , linux-efi@vger.kernel.org, "linux-kernel@vger.kernel.org Will Deacon" Date: Tue, 20 Jul 2021 21:14:12 +1000 User-Agent: Evolution 3.36.5-0ubuntu1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210720_041516_586319_C3E8070C X-CRM114-Status: GOOD ( 16.36 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org If efi_random_alloc() fails, we still try to use EFI_KIMG_ALIGN instead of MIN_KIMG_ALIGN to check the kernel image alignment, which is incorrect, we need to fallback to MIN_KIMG_ALIGN (2M). This removes the not-that-useful min_kimg_align helper and instead uses the appropriate aligment in the respective call sites: efi_random_alloc() always wants EFI_KIMG_ALIGN as this is only used when kaslr is on, and all other cases go into alignment check code which always need to check (and enforce) MIN_KIMG_ALIGN Signed-off-by: Benjamin Herrenschmidt Fixes: 7c116db24d94 (efi/libstub/arm64: Retain 2MB kernel Image alignment if !KASLR) --- drivers/firmware/efi/libstub/arm64-stub.c | 27 ++++++++++------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index 7bf0a7acae5e..e264ff90ba03 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -34,18 +34,6 @@ efi_status_t check_platform_features(void) return EFI_SUCCESS; } -/* - * Although relocatable kernels can fix up the misalignment with respect to - * MIN_KIMG_ALIGN, the resulting virtual text addresses are subtly out of - * sync with those recorded in the vmlinux when kaslr is disabled but the - * image required relocation anyway. Therefore retain 2M alignment unless - * KASLR is in use. - */ -static u64 min_kimg_align(void) -{ - return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; -} - efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *image_size, unsigned long *reserve_addr, @@ -84,15 +72,24 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, /* * If KASLR is enabled, and we have some randomness available, * locate the kernel at a randomized offset in physical memory. + * + * In that case, we don't need to preserve the 2M alignment */ - status = efi_random_alloc(*reserve_size, min_kimg_align(), + status = efi_random_alloc(*reserve_size, EFI_KIMG_ALIGN, reserve_addr, phys_seed); } else { status = EFI_OUT_OF_RESOURCES; } if (status != EFI_SUCCESS) { - if (IS_ALIGNED((u64)_text, min_kimg_align())) { + /* + * Although relocatable kernels can fix up the misalignment with respect to + * MIN_KIMG_ALIGN, the resulting virtual text addresses are subtly out of + * sync with those recorded in the vmlinux when kaslr is disabled but the + * image required relocation anyway. Therefore retain 2M alignment unless + * KASLR is in use. + */ + if (IS_ALIGNED((u64)_text, MIN_KIMG_ALIGN)) { /* * Just execute from wherever we were loaded by the * UEFI PE/COFF loader if the alignment is suitable. @@ -103,7 +100,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, - ULONG_MAX, min_kimg_align()); + ULONG_MAX, MIN_KIMG_ALIGN); if (status != EFI_SUCCESS) { efi_err("Failed to relocate kernel\n");