Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp3354822ybl; Mon, 19 Aug 2019 17:21:36 -0700 (PDT) X-Google-Smtp-Source: APXvYqwGyJhQk278Kz0MYV5EY+GwkljS0UI9ko4LfDu8lHMizrg+jOyisuwDB6hL0FT9VqxOl03Z X-Received: by 2002:a63:a302:: with SMTP id s2mr22478948pge.125.1566260496084; Mon, 19 Aug 2019 17:21:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566260496; cv=none; d=google.com; s=arc-20160816; b=jT2y4tiWClqk212fE8xV3m214/u3SJvU9NlTk+45r299N5N0cBes2qcLIn3xiYZBbG py5J2SztCqIHOnzW+8aqMV4aD0g2tW81Hfi0Ikvj94n0SNAp5X96Pb2yCQk/mFn7xA8a Mcp0RGrseEMTDTXKKSegay4PSJOIy9C0ovJ+4nURKggXURXD9bepf7lLHZvbw9PjXKer FhNGaRl2Hv4cQDTVHBLptICwPvLjvxe9RGlFST/BzdwqDxhXI6pL+aEUfD4wIDI6QScU 2Q7vNUJGyYZhgH+tsg5Ouo/rTYYigWXjoLhsJUEpGhwOo3xGYYYXr3lOFUvRaOz0tOv1 nK9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=8MAs1bAHSj1uxDRGspfRRmO6rZPmngolbnzqCoks0Vc=; b=zLKcvu5dJqhiPv9790AGLUPelSoSlv72gj5xqSMLCNAQJnk9KwlNXfkojE7R8QEEg1 WuYMRHjIvzvRxYA08TwmpGdus5CB8tGDv70OT5xRXl0bmkeSxSlntz7tBucs4G0XkKEy TKI8+sHKkkaMVYHSVif5FuswY0HxqIQVz76Kr4rRipxEu2xQt38vO27WrAyIXm4R/HEB GpC9uSFiXkfgB9FthEvxH70WdT6KmoMXqjWumYw5fw6hZbXzFnWTZTH92oxHgYUTvwve FcoT9XTJ1GQav7wnkaLW75gN5uCNLpnpYWzNGclIaz709HFPkfZoISIs2I+3EjldEb+R +1og== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=rFrsVdFy; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x203si10903984pgx.545.2019.08.19.17.21.21; Mon, 19 Aug 2019 17:21:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=rFrsVdFy; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729070AbfHTASw (ORCPT + 99 others); Mon, 19 Aug 2019 20:18:52 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:51525 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729058AbfHTASu (ORCPT ); Mon, 19 Aug 2019 20:18:50 -0400 Received: by mail-pf1-f201.google.com with SMTP id v134so3514979pfc.18 for ; Mon, 19 Aug 2019 17:18:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=8MAs1bAHSj1uxDRGspfRRmO6rZPmngolbnzqCoks0Vc=; b=rFrsVdFyDTlYO5eKPhECNudu7viLzyB1MK461YJk3u+HRS1MUeClFo3geJju4v4uUq 2igSPKLKcJeNmcr7e8MEE1GCr5CH2FGUfBG3HU5OJKbDCIBzv8TUQeu23Is59KlryJA0 Hi5JNAckRaPex3WqBGF9RBKcNyjIhA8JbYxeHVFkQSRIPPcqEc2ZylY40urAzYXkO1gI Oi2dWLqa76HI306IQxZQthmSowv+FWJyG4yA0X0UgrDqGaUVYWS4pCGb7XvBJnGjrL5C G1ZBt5u5ay+Nq5aw1uLGZLVUASS7NTuyYuehjjdi7/8he5y0li/VnUU1TzjlwMaglmBr piHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=8MAs1bAHSj1uxDRGspfRRmO6rZPmngolbnzqCoks0Vc=; b=EFqkemyTSp/GhMz4epmdu2cQUOFkeedWZYdiOIv2mD6HhxE71KGJzDqkYQgZNBbp0y B/kvTODNAkFqbg0dwNb51+HtDXlNjxepNV6ztQ35sv79LoncqIbZSSli9J+SPPc8uDUl +x2vTdJ4u6mcKHFKFp0/1THPtq3Vvy3+83YIvm0BKViHTn8S0+H5/O3XXBQ87QkAiFu1 GEEMY7oMQ+Tm0Obhn8D0YGWuUzXxtibB95DhxB0A56Ec9BluDekHf5dKEo+qlneSFRB4 rRdVOFKXOy94ojAk1vjyKZAS0Si5Hjb5ysA+IT63CAL8/Q3e4Nhd3SEc7aMbgxwu0Q6I lVvA== X-Gm-Message-State: APjAAAW+sGFkUmWUl/eYDn5uxI8HUCZEsyYfhFcRJV982x+70yQjMLCU ko3D4UHL56Sareftha6DFHAOfOw0hTzeqLzyRDuNuw== X-Received: by 2002:a63:a66:: with SMTP id z38mr22941929pgk.247.1566260329023; Mon, 19 Aug 2019 17:18:49 -0700 (PDT) Date: Mon, 19 Aug 2019 17:17:51 -0700 In-Reply-To: <20190820001805.241928-1-matthewgarrett@google.com> Message-Id: <20190820001805.241928-16-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190820001805.241928-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog Subject: [PATCH V40 15/29] acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down From: Matthew Garrett To: jmorris@namei.org Cc: linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, Josh Boyer , David Howells , Matthew Garrett , Kees Cook , Dave Young , linux-acpi@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Josh Boyer This option allows userspace to pass the RSDP address to the kernel, which makes it possible for a user to modify the workings of hardware. Reject the option when the kernel is locked down. This requires some reworking of the existing RSDP command line logic, since the early boot code also makes use of a command-line passed RSDP when locating the SRAT table before the lockdown code has been initialised. This is achieved by separating the command line RSDP path in the early boot code from the generic RSDP path, and then copying the command line RSDP into boot params in the kernel proper if lockdown is not enabled. If lockdown is enabled and an RSDP is provided on the command line, this will only be used when parsing SRAT (which shouldn't permit kernel code execution) and will be ignored in the rest of the kernel. (Modified by Matthew Garrett in order to handle the early boot RSDP environment) Signed-off-by: Josh Boyer Signed-off-by: David Howells Signed-off-by: Matthew Garrett Reviewed-by: Kees Cook cc: Dave Young cc: linux-acpi@vger.kernel.org Signed-off-by: James Morris --- arch/x86/boot/compressed/acpi.c | 19 +++++++++++++------ arch/x86/include/asm/acpi.h | 9 +++++++++ arch/x86/include/asm/x86_init.h | 2 ++ arch/x86/kernel/acpi/boot.c | 5 +++++ arch/x86/kernel/x86_init.c | 1 + drivers/acpi/osl.c | 14 +++++++++++++- include/linux/acpi.h | 6 ++++++ 7 files changed, 49 insertions(+), 7 deletions(-) diff --git a/arch/x86/boot/compressed/acpi.c b/arch/x86/boot/compressed/acpi.c index ad84239e595e..e726e9b44bb1 100644 --- a/arch/x86/boot/compressed/acpi.c +++ b/arch/x86/boot/compressed/acpi.c @@ -26,7 +26,7 @@ struct mem_vector immovable_mem[MAX_NUMNODES*2]; */ #define MAX_ADDR_LEN 19 -static acpi_physical_address get_acpi_rsdp(void) +static acpi_physical_address get_cmdline_acpi_rsdp(void) { acpi_physical_address addr = 0; @@ -215,10 +215,7 @@ acpi_physical_address get_rsdp_addr(void) { acpi_physical_address pa; - pa = get_acpi_rsdp(); - - if (!pa) - pa = boot_params->acpi_rsdp_addr; + pa = boot_params->acpi_rsdp_addr; if (!pa) pa = efi_get_rsdp_addr(); @@ -240,7 +237,17 @@ static unsigned long get_acpi_srat_table(void) char arg[10]; u8 *entry; - rsdp = (struct acpi_table_rsdp *)(long)boot_params->acpi_rsdp_addr; + /* + * Check whether we were given an RSDP on the command line. We don't + * stash this in boot params because the kernel itself may have + * different ideas about whether to trust a command-line parameter. + */ + rsdp = (struct acpi_table_rsdp *)get_cmdline_acpi_rsdp(); + + if (!rsdp) + rsdp = (struct acpi_table_rsdp *)(long) + boot_params->acpi_rsdp_addr; + if (!rsdp) return 0; diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index aac686e1e005..bc9693c9107e 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -117,6 +117,12 @@ static inline bool acpi_has_cpu_in_madt(void) return !!acpi_lapic; } +#define ACPI_HAVE_ARCH_SET_ROOT_POINTER +static inline void acpi_arch_set_root_pointer(u64 addr) +{ + x86_init.acpi.set_root_pointer(addr); +} + #define ACPI_HAVE_ARCH_GET_ROOT_POINTER static inline u64 acpi_arch_get_root_pointer(void) { @@ -125,6 +131,7 @@ static inline u64 acpi_arch_get_root_pointer(void) void acpi_generic_reduced_hw_init(void); +void x86_default_set_root_pointer(u64 addr); u64 x86_default_get_root_pointer(void); #else /* !CONFIG_ACPI */ @@ -138,6 +145,8 @@ static inline void disable_acpi(void) { } static inline void acpi_generic_reduced_hw_init(void) { } +static inline void x86_default_set_root_pointer(u64 addr) { } + static inline u64 x86_default_get_root_pointer(void) { return 0; diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index b85a7c54c6a1..d584128435cb 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -134,10 +134,12 @@ struct x86_hyper_init { /** * struct x86_init_acpi - x86 ACPI init functions + * @set_root_poitner: set RSDP address * @get_root_pointer: get RSDP address * @reduced_hw_early_init: hardware reduced platform early init */ struct x86_init_acpi { + void (*set_root_pointer)(u64 addr); u64 (*get_root_pointer)(void); void (*reduced_hw_early_init)(void); }; diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 17b33ef604f3..04205ce127a1 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1760,6 +1760,11 @@ void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size) e820__update_table_print(); } +void x86_default_set_root_pointer(u64 addr) +{ + boot_params.acpi_rsdp_addr = addr; +} + u64 x86_default_get_root_pointer(void) { return boot_params.acpi_rsdp_addr; diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c index 50a2b492fdd6..d0b8f5585a73 100644 --- a/arch/x86/kernel/x86_init.c +++ b/arch/x86/kernel/x86_init.c @@ -95,6 +95,7 @@ struct x86_init_ops x86_init __initdata = { }, .acpi = { + .set_root_pointer = x86_default_set_root_pointer, .get_root_pointer = x86_default_get_root_pointer, .reduced_hw_early_init = acpi_generic_reduced_hw_init, }, diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index cc7507091dec..b7c3aeb175dd 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -180,8 +181,19 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) acpi_physical_address pa; #ifdef CONFIG_KEXEC - if (acpi_rsdp) + /* + * We may have been provided with an RSDP on the command line, + * but if a malicious user has done so they may be pointing us + * at modified ACPI tables that could alter kernel behaviour - + * so, we check the lockdown status before making use of + * it. If we trust it then also stash it in an architecture + * specific location (if appropriate) so it can be carried + * over further kexec()s. + */ + if (acpi_rsdp && !security_locked_down(LOCKDOWN_ACPI_TABLES)) { + acpi_arch_set_root_pointer(acpi_rsdp); return acpi_rsdp; + } #endif pa = acpi_arch_get_root_pointer(); if (pa) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d315d86844e4..268a4d91f54c 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -632,6 +632,12 @@ bool acpi_gtdt_c3stop(int type); int acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem, int *timer_count); #endif +#ifndef ACPI_HAVE_ARCH_SET_ROOT_POINTER +static inline void acpi_arch_set_root_pointer(u64 addr) +{ +} +#endif + #ifndef ACPI_HAVE_ARCH_GET_ROOT_POINTER static inline u64 acpi_arch_get_root_pointer(void) { -- 2.23.0.rc1.153.gdeed80330f-goog