From patchwork Fri Aug 25 15:50:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 111032 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp1219222qge; Fri, 25 Aug 2017 08:59:37 -0700 (PDT) X-Received: by 10.101.76.139 with SMTP id m11mr3111987pgt.160.1503676777243; Fri, 25 Aug 2017 08:59:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503676777; cv=none; d=google.com; s=arc-20160816; b=c0l8JkiUCEnF2vuhmkN7oFnyXwS8Hxmb2yP/yX5M2nAEUiNd28tJ2OcpLZazUsUDce qGj5SQYkozQAbQrfTUzOzFeQMf4QB3k95U0vPOSTY7Auns29xi5Yro7WhYuTX59CcsmG IVf38XR4DBT9dAnccc/3rEtbduGrlJOnjKgPt2A0H6nFwwjuR6MZUxQhgp0HY9IDOPx2 81WM03cYkkJ8PJaGDF6LVD9L15cwKNq5JabxktlFx7U74zklqrvykW9iHaktKlMoBfPv mEjrCZzmkqthIrKyab2bHuM6RO+Og/dqmvWktUK4FfzyE65pxPEWDCx7wDQjCRcLxK0c HH2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=yeh1AHTMnB28aqq2EkdnHsurG1pADBSntYpp9jxtf5Y=; b=monu7R189CmdBEOqId0wRWt7wK6OM0HnLS/l3HEh1MsKC66roxP4aJ4/CzkH9F5RmW 6G8lsLDmsPKVB6p4TLRoSC/DzoZbUKJqBfZkjKwV+GQOVfgDn1JponAuM/ylxCXbKw5K UmJ/lMuL3Fd7TXbbOjBksdr0g/kx+gsiqnVLk1C0bwsn3Oi2i7I1u8Y+Zsxaw+Xpmp/L gXkcBTSK+1Qb4bR9Q3DtvOGC7gCAjTiH0BS079yGlnz23L+qi2LXW82et0nFomD1hfaw z8upYN5NnInoqey/U8KYbhivsBvW/LjHhFTwTWHS5iChYaEcUbBp5AA/vbqmmPEef3/X COQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=JvzDtQ2b; 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=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q4si5489004pli.267.2017.08.25.08.59.36; Fri, 25 Aug 2017 08:59:37 -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=@linaro.org header.s=google header.b=JvzDtQ2b; 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=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934112AbdHYP7e (ORCPT + 26 others); Fri, 25 Aug 2017 11:59:34 -0400 Received: from mail-wr0-f182.google.com ([209.85.128.182]:34539 "EHLO mail-wr0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934089AbdHYP73 (ORCPT ); Fri, 25 Aug 2017 11:59:29 -0400 Received: by mail-wr0-f182.google.com with SMTP id z91so692846wrc.1 for ; Fri, 25 Aug 2017 08:59:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yeh1AHTMnB28aqq2EkdnHsurG1pADBSntYpp9jxtf5Y=; b=JvzDtQ2bCtoW4OPJPfhIrzMvEZTSIjVJNdSTCyVqhcTOHmpTWG24TSSlB7Kz/ufSme X7a2LfQ7gBNhCyf1nGfcNqcSGqB/HIuxoCZRQSn6Mkwj4cT67MoEx+pHnPCwUoqLi2NC 8q6xDY70qvU7X2wfmyenSIyhcoVm5RwIxGRdo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yeh1AHTMnB28aqq2EkdnHsurG1pADBSntYpp9jxtf5Y=; b=RpjQLgcJ3qcL4gtqWGwE/UhkdOKxzIj9x9jCLa2HtfFaihNgaWdKmmjlCwnjxvpbOh aQtMF9DdFSUuf1SrBr9qK/OyF5VXy9zsPbxT4QHl15oNSm6Mgvy7Bfgi7uA4QYByy3UT xVqNLrYtPQ/b/uTBshH1iVT8Rs54APEU5NxdQhB0Va0a9drlwrG6IAXm0D22nOTrVEOT +OuYWOL2ce2426LA1Pm5ejgr0LX6PrCKSqYYUBTWu2KYguiTc9TpaLDRuNT66CukQcwj J1h4VUkawyoanH99xGBaLWtcJz0FvfFLNvUiV1MS5wer0Y8Y6yUo6sjdQCcYIo+Bygg3 OYdg== X-Gm-Message-State: AHYfb5jAmMWDdzLSBAmFQHje0K0iQlC2X/7kqwEY6Oxb5MJzniH/OxQr bcVxPrLOZGKEhSq4 X-Received: by 10.223.186.13 with SMTP id o13mr7139428wrg.129.1503676767613; Fri, 25 Aug 2017 08:59:27 -0700 (PDT) Received: from localhost.localdomain ([105.137.125.182]) by smtp.gmail.com with ESMTPSA id b96sm14507757wrd.94.2017.08.25.08.59.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Aug 2017 08:59:26 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Matthew Garrett , Ard Biesheuvel , linux-kernel@vger.kernel.org, Matt Fleming Subject: [PATCH 1/5] efi/libstub: Enable reset attack mitigation Date: Fri, 25 Aug 2017 16:50:15 +0100 Message-Id: <20170825155019.6740-2-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170825155019.6740-1-ard.biesheuvel@linaro.org> References: <20170825155019.6740-1-ard.biesheuvel@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Matthew Garrett If a machine is reset while secrets are present in RAM, it may be possible for code executed after the reboot to extract those secrets from untouched memory. The Trusted Computing Group specified a mechanism for requesting that the firmware clear all RAM on reset before booting another OS. This is done by setting the MemoryOverwriteRequestControl variable at startup. If userspace can ensure that all secrets are removed as part of a controlled shutdown, it can reset this variable to 0 before triggering a hardware reboot. Signed-off-by: Matthew Garrett Cc: Matt Fleming Signed-off-by: Ard Biesheuvel --- arch/x86/boot/compressed/eboot.c | 3 ++ drivers/firmware/efi/Kconfig | 10 ++++++ drivers/firmware/efi/libstub/Makefile | 1 + drivers/firmware/efi/libstub/arm-stub.c | 3 ++ drivers/firmware/efi/libstub/tpm.c | 58 +++++++++++++++++++++++++++++++++ include/linux/efi.h | 7 ++++ 6 files changed, 82 insertions(+) create mode 100644 drivers/firmware/efi/libstub/tpm.c -- 2.11.0 diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c3e869eaef0c..a1686f3dc295 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -997,6 +997,9 @@ struct boot_params *efi_main(struct efi_config *c, if (boot_params->secure_boot == efi_secureboot_mode_unset) boot_params->secure_boot = efi_get_secureboot(sys_table); + /* Ask the firmware to clear memory on unclean shutdown */ + efi_enable_reset_attack_mitigation(sys_table); + setup_graphics(boot_params); setup_efi_pci(boot_params); diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 394db40ed374..2b4c39fdfa91 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -151,6 +151,16 @@ config APPLE_PROPERTIES If unsure, say Y if you have a Mac. Otherwise N. +config RESET_ATTACK_MITIGATION + bool "Reset memory attack mitigation" + depends on EFI_STUB + help + Request that the firmware clear the contents of RAM after a reboot + using the TCG Platform Reset Attack Mitigation specification. This + protects against an attacker forcibly rebooting the system while it + still contains secrets in RAM, booting another OS and extracting the + secrets. + endmenu config UEFI_CPER diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index cf81e6cf5ae8..dedf9bde44db 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -30,6 +30,7 @@ OBJECT_FILES_NON_STANDARD := y KCOV_INSTRUMENT := n lib-y := efi-stub-helper.o gop.o secureboot.o +lib-$(CONFIG_RESET_ATTACK_MITIGATION) += tpm.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index 8181ac179d14..1cb2d1c070c3 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -192,6 +192,9 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, goto fail_free_cmdline; } + /* Ask the firmware to clear memory on unclean shutdown */ + efi_enable_reset_attack_mitigation(sys_table); + secure_boot = efi_get_secureboot(sys_table); /* diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c new file mode 100644 index 000000000000..6224cdbc9669 --- /dev/null +++ b/drivers/firmware/efi/libstub/tpm.c @@ -0,0 +1,58 @@ +/* + * TPM handling. + * + * Copyright (C) 2016 CoreOS, Inc + * Copyright (C) 2017 Google, Inc. + * Matthew Garrett + * + * This file is part of the Linux kernel, and is made available under the + * terms of the GNU General Public License version 2. + */ +#include +#include + +#include "efistub.h" + +static const efi_char16_t efi_MemoryOverWriteRequest_name[] = { + 'M', 'e', 'm', 'o', 'r', 'y', 'O', 'v', 'e', 'r', 'w', 'r', 'i', 't', + 'e', 'R', 'e', 'q', 'u', 'e', 's', 't', 'C', 'o', 'n', 't', 'r', 'o', + 'l', 0 +}; + +#define MEMORY_ONLY_RESET_CONTROL_GUID \ + EFI_GUID(0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29) + +#define get_efi_var(name, vendor, ...) \ + efi_call_runtime(get_variable, \ + (efi_char16_t *)(name), (efi_guid_t *)(vendor), \ + __VA_ARGS__) + +#define set_efi_var(name, vendor, ...) \ + efi_call_runtime(set_variable, \ + (efi_char16_t *)(name), (efi_guid_t *)(vendor), \ + __VA_ARGS__) + +/* + * Enable reboot attack mitigation. This requests that the firmware clear the + * RAM on next reboot before proceeding with boot, ensuring that any secrets + * are cleared. If userland has ensured that all secrets have been removed + * from RAM before reboot it can simply reset this variable. + */ +void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) +{ + u8 val = 1; + efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID; + efi_status_t status; + unsigned long datasize = 0; + + status = get_efi_var(efi_MemoryOverWriteRequest_name, &var_guid, + NULL, &datasize, NULL); + + if (status == EFI_NOT_FOUND) + return; + + set_efi_var(efi_MemoryOverWriteRequest_name, &var_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), &val); +} diff --git a/include/linux/efi.h b/include/linux/efi.h index 8269bcb8ccf7..12e05118657c 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1497,6 +1497,13 @@ enum efi_secureboot_mode { }; enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table); +#ifdef CONFIG_RESET_ATTACK_MITIGATION +void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg); +#else +static inline void +efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { } +#endif + /* * Arch code can implement the following three template macros, avoiding * reptition for the void/non-void return cases of {__,}efi_call_virt():