From patchwork Mon May 22 07:14:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 97114 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1264123vqo; Mon, 22 May 2023 00:22:48 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ59o5rRrkOSzfLpZZwCiE70kfODqWTCtlirDT8oFpt0k3V2Yy3J4X2YzKoHSNESh+AI83EP X-Received: by 2002:a05:6a21:6d86:b0:10a:e556:70ec with SMTP id wl6-20020a056a216d8600b0010ae55670ecmr6113336pzb.7.1684740168299; Mon, 22 May 2023 00:22:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684740168; cv=none; d=google.com; s=arc-20160816; b=izWUwWKWDlaIn5Q8wePPDR9R2+nirt/+0jbpEuWwwTgUw6UdwzjIl+VNv9ACG1aQHe inAme0fxtCZ1Xk1u9wIxbb8mJkEQEficHGk+7Qggb4JUIosQcp3PhZexBTrIfH+TKzNl Si12hDfeTsbZohaCZnZSw/9s11oUYjP+BJH7pevNj6sULBnq5lobjpb9xMHOjPmFOjvH eyizGNbq0/KqjPcXhtUyJbW7ZVOxkAbz3JNYHxeFjEOhNd0i17uJ+y/pafc7mPoB592z xbTbDWopmJD3vw/JWWbpvEJ6ZPdNKinvvUnwdqtnupkDC5zuuW4aPeAm0Y5irOf/GyyP yhqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=C3Bv8cUcHA/U96JPhUJqv2V3mQnBjuUWzbViEU2OyOo=; b=N/bYnS09n2ru5nF8FK0sJGJ+zy1r3kreARyN77Wjyzlq8kNJvlXg8j0M4RlOSpV16j vVSLe4E0ZeTcc4oe0JaT0nTPkcD+SrWd8hLuCoGEBxXoXV0MjOO8HKEcSe9/EWXNkoay o8WrGkW/+Co5zC8Zk6VLbWoT3X2lqbjnXwE+Km3ROL4evFoGYEsLqIrCH95Wd08u6oro xqvX+p/2EY5Z5QTQrQkDHUW8AQ2xwZ6bP/LqmWw10r3dbyosJJ4+L8+9UUypfAU4Rbg/ CyebwAEgJgYUBDBfftqKrZj+nO1ZxxRom2UYA4ovwsLP+5fC3P8BMaRFqmUMNjDWi2FW XzPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=M1Cqkfr0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x71-20020a63864a000000b0053b52fed717si3184011pgd.864.2023.05.22.00.22.32; Mon, 22 May 2023 00:22:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=M1Cqkfr0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232460AbjEVHQr (ORCPT + 99 others); Mon, 22 May 2023 03:16:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232483AbjEVHQI (ORCPT ); Mon, 22 May 2023 03:16:08 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DD8EE7E; Mon, 22 May 2023 00:15:33 -0700 (PDT) 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 dfw.source.kernel.org (Postfix) with ESMTPS id C96BB61DF3; Mon, 22 May 2023 07:15:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E058C433A1; Mon, 22 May 2023 07:15:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684739732; bh=9rSHT6To50AeTePxnLLsddpAkNAPINJ4d8fPXZY5ZkI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M1Cqkfr0Z9+BTOytdvTGksJEHot4TmJ+SSmPbxA8uA0H0JIyxxXr7OrYxAThdfSBG iYflMl6nlU4kJa7YVVsFDDxSo3Ra8bxKCcoKC7q/k4BCvsnzX634ypUn0cHqaTHkVR dI8osqfR4xcpswOqzBhqtXf7Z3VV/+yL8Pq95Fd/dZAp/RtNNI/v7Q4/F8hNh140vO JhXdsG4ssDy37iY2/g3PC3rhfg/y3tgvz2LrhycqSPk3rkUIDJHCamrhbej2mKssnL /Kv+9i6uKQQRAvYrPNR4cLqIiJY3Ui1msoBE317GRBcyFoty923VZjR8uI0UIONO3f 3SIKPG1mpFOog== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , Evgeniy Baskov , Borislav Petkov , Andy Lutomirski , Dave Hansen , Ingo Molnar , Peter Zijlstra , Thomas Gleixner , Alexey Khoroshilov , Peter Jones , Gerd Hoffmann , Dave Young , Mario Limonciello , Kees Cook , Tom Lendacky , "Kirill A . Shutemov" , Linus Torvalds Subject: [PATCH v3 14/21] x86/efistub: Prefer EFI memory attributes protocol over DXE services Date: Mon, 22 May 2023 09:14:08 +0200 Message-Id: <20230522071415.501717-15-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230522071415.501717-1-ardb@kernel.org> References: <20230522071415.501717-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3293; i=ardb@kernel.org; h=from:subject; bh=9rSHT6To50AeTePxnLLsddpAkNAPINJ4d8fPXZY5ZkI=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JISVbzG71mWflt6IOMnrNKp69L/qBw85rtQ8dUnoi11ycK SDGfnJ9RykLgxgHg6yYIovA7L/vdp6eKFXrPEsWZg4rE8gQBi5OAZiISh3DP7Up868GXGqfeiyx ft+nFzm7Gn/4NHqoKKilLbRZ58AT1sTwT2npF6eSaXWLZ/KqbN+UImqlvE30U35g2+EJXo4L5mQ 4cQAA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1766578106671315929?= X-GMAIL-MSGID: =?utf-8?q?1766578106671315929?= Currently, the EFI stub relies on DXE services in some cases to clear non-execute restrictions from page allocations that need to be executable. This is dodgy, because DXE services are not specified by UEFI but by PI, and they are not intended for consumption by OS loaders. However, no alternative existed at the time. Now, there is a new UEFI protocol that should be used instead, so if it exists, prefer it over the DXE services calls. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/x86-stub.c | 29 ++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index 229def7d9b028ceb..fcdae5db0c63c7e5 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -26,6 +26,7 @@ const efi_system_table_t *efi_system_table; const efi_dxe_services_table_t *efi_dxe_table; u32 image_offset __section(".data"); static efi_loaded_image_t *image = NULL; +static efi_memory_attribute_protocol_t *memattr; static efi_status_t preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom) @@ -222,12 +223,18 @@ void efi_adjust_memory_range_protection(unsigned long start, unsigned long rounded_start, rounded_end; unsigned long unprotect_start, unprotect_size; - if (efi_dxe_table == NULL) - return; - rounded_start = rounddown(start, EFI_PAGE_SIZE); rounded_end = roundup(start + size, EFI_PAGE_SIZE); + if (memattr != NULL) { + efi_call_proto(memattr, clear_memory_attributes, rounded_start, + rounded_end - rounded_start, EFI_MEMORY_XP); + return; + } + + if (efi_dxe_table == NULL) + return; + /* * Don't modify memory region attributes, they are * already suitable, to lower the possibility to @@ -766,6 +773,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, struct boot_params *boot_params) { + efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; unsigned long bzimage_addr = (unsigned long)startup_32; unsigned long buffer_start, buffer_end; struct setup_header *hdr = &boot_params->hdr; @@ -777,13 +785,18 @@ void __noreturn efi_stub_entry(efi_handle_t handle, if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) efi_exit(handle, EFI_INVALID_PARAMETER); - efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); - if (efi_dxe_table && - efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { - efi_warn("Ignoring DXE services table: invalid signature\n"); - efi_dxe_table = NULL; + if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) { + efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID); + if (efi_dxe_table && + efi_dxe_table->hdr.signature != EFI_DXE_SERVICES_TABLE_SIGNATURE) { + efi_warn("Ignoring DXE services table: invalid signature\n"); + efi_dxe_table = NULL; + } } + /* grab the memory attributes protocol if it exists */ + efi_bs_call(locate_protocol, &guid, NULL, (void **)&memattr); + if (IS_ENABLED(CONFIG_X86_64)) { status = efi_setup_5level_paging(); if (status != EFI_SUCCESS) {