From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3968121F2AF64 for ; Thu, 28 Sep 2017 05:52:04 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C4D9DC109851; Thu, 28 Sep 2017 12:55:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C4D9DC109851 Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=lersek@redhat.com Received: from lacos-laptop-7.usersys.redhat.com (ovpn-120-73.rdu2.redhat.com [10.10.120.73]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8E80086E73; Thu, 28 Sep 2017 12:55:17 +0000 (UTC) To: Jiewen Yao Cc: Ladi Prosek , edk2-devel-01 From: Laszlo Ersek Message-ID: <039cf353-80fb-9f20-6ad2-f52517ab4de7@redhat.com> Date: Thu, 28 Sep 2017 14:55:16 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 28 Sep 2017 12:55:18 +0000 (UTC) Subject: multiple levels of support for MOR / MORLock X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Sep 2017 12:52:05 -0000 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Hi Jiewen, my colleague Ladi (CC'd) reported an issue about MORLock in OVMF (and also analyzed it in great depth): https://bugzilla.redhat.com/show_bug.cgi?id=1496170 Here's my understanding of the "MemoryOverwriteRequestControl" and "MemoryOverwriteRequestControlLock" variables: (1) The "MemoryOverwriteRequestControl" variable comes from the "TCG Platform Reset Attack Mitigation Specification" at . (2) The "MemoryOverwriteRequestControlLock" variable is a Microsoft-only addition, called "Secure MOR implementation", from . (3) "winload.efi" accepts the following cases as "valid": (3a) Both MORC and MORCL are present. In this case MORC is set and MORCL is used to lock both MORC and MORCL. (3b) MORC is present, MORCL is absent. In this case "winload.efi" thinks that the platform follows the TCG spec from (1), and does not support the Microsoft spec from (2). MORC is set, but it is not locked. (3c) Both MORC and MORCL are missing. "winload.efi" thinks that the platform does not know about either spec, and "winload.efi" accepts that as OK. However "winload.efi"rejects the following case as "invalid": (3d) MORCL is present, but MORC is missing. In my opinion, "winload.efi" is right to reject this, because it implies that the platform supports the *dependent* spec (2), but does not support the *prerequisite* spec (1). In edk2, MORC is implemented by the "SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf" driver. A platform is allowed *not* to include this driver, even if it supports SMM. OVMF is such a platform; it does not include "TcgMor.inf". However, MORCL is initialized in the variable driver, independently of platform support for MORC: * If the platform includes the SMM driver backend, then we have: VariableWriteServiceInitialize() [MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c] MorLockInit() [MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c] SetMorLockVariable() [MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c] // // create or set variable // with contents 0 // * If the platform includes no SMM backend for the variable services, then we have: VariableWriteServiceInitialize() [MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c] MorLockInit() [MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockDxe.c] // // delete the variable and // also lock it so that // nothing else can // create it // In my opinion, if the platform includes the SMM backend, but does not support "MORC", then the "TcgMorLockSmm.c" code is incorrect; instead we should do what we see in "TcgMorLockDxe.c". In other words, SMM support in itself is no indication for claiming support for MORCL. I suggest that we introduce a new PCD for this ("PcdSupportMemoryOverwriteRequest"), in "SecurityPkg.dec", with type UINT8. It should be a bitmap: - BIT0 -- If clear, then MORC is not supported, and BIT1 is ignored. Otherwise, MORC is supported, and BIT1 is meaningful. - BIT1 -- If clear, then MORCL is unsupported. If set, then MORCL is supported. - BIT2 through BIT7 are reserved. In turn, here's how the new PCD should be handled, in my opinion: - MorLockInit() in "TcgMorLockDxe.c" should do what it does now, but it should also assert that BIT1 is clear. - MorLockInit() in "TcgMorLockSmm.c" should do what it does now *only* if BIT1 is set. Otherwise (i.e., BIT1 is clear), it should do what "TcgMorLockDxe.c" does now. - If BIT0 is clear (MORC is not supported), then both MorLockInit() functions should delete, and lock, the MORC variable too, so that nothing else can create it. What do you think? Thank you! Laszlo