From patchwork Sun Feb 26 18:30:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94530 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp566241qgi; Sun, 26 Feb 2017 10:30:37 -0800 (PST) X-Received: by 10.98.221.141 with SMTP id w135mr16481687pff.109.1488133837865; Sun, 26 Feb 2017 10:30:37 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id b80si11721296pfd.138.2017.02.26.10.30.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Feb 2017 10:30:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 72BF782126; Sun, 26 Feb 2017 10:30:37 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x231.google.com (mail-wm0-x231.google.com [IPv6:2a00:1450:400c:c09::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E958B82126 for ; Sun, 26 Feb 2017 10:30:35 -0800 (PST) Received: by mail-wm0-x231.google.com with SMTP id v186so47150662wmd.0 for ; Sun, 26 Feb 2017 10:30:35 -0800 (PST) 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=ZLo/mBL996UMzCYelE+fogyf+t/RimtJ0Aw/ZCfm+o4=; b=EuKQxoubJbBH6y8B/4O9L+6rTjjUb9zxgx9I1g4QiIuonUgGoB+zsIyVBrn6iDf7ik mlG3wgQF2fQzxLlnfshnEv73JM3FxRCch/nsj4Sbcq53PBAOyNRl2I3Ky2OEp7qZ+KFM WinblUGz69sA7EIFtXEjD+IestKvYlgSiNkI8= 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=ZLo/mBL996UMzCYelE+fogyf+t/RimtJ0Aw/ZCfm+o4=; b=JE+TwiuJ7ViLdBkuYiv14UqM4Qh6UL73W/LC13DCKLnVacvrXVZrYWjA3Co+mKMOHh V1SmQgYhpi+e3LuX/VWnO3xsWBR61FdMTs8v0aFk+l0Ft8I4Xo0ZxY2+dwFyyPD4BTjG kBf4VJjFmpRb/kgY7ONayXZjSrBEVOER4W23k75IDw9fqVJVPx/hdGHi+TtfaaWy991j 3hRZplvJ0n79DS8mp3IkhAMd4gE+NzY/+rbMv0b8+lJAWIDfz0LT8h0uUXfVYfVH6KLu 6SiT5CyBVWgv13HAxetw5LlOkLgjuKUmytFDTkXF1ewOCPADV8eMWKNzh4OlD8kj4EdN ASBQ== X-Gm-Message-State: AMke39lK/TY4DLPm9zYh4RHyzqIUg9v1won9Ipn4qiOBtXr+xh1ONDO9FbEBh9+WoGviytku X-Received: by 10.28.91.1 with SMTP id p1mr10267909wmb.102.1488133834500; Sun, 26 Feb 2017 10:30:34 -0800 (PST) Received: from localhost.localdomain ([105.149.201.216]) by smtp.gmail.com with ESMTPSA id s103sm4499474wrc.6.2017.02.26.10.30.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 26 Feb 2017 10:30:33 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, jiewen.yao@intel.com, leif.lindholm@linaro.org Date: Sun, 26 Feb 2017 18:30:00 +0000 Message-Id: <1488133805-4773-2-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 1/6] ArmPkg/CpuDxe: ignore attribute changes during SyncCacheConfig() X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: feng.tian@intel.com, Ard Biesheuvel , afish@apple.com, liming.gao@Intel.com, michael.d.kinney@intel.com, lersek@redhat.com, star.zeng@intel.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" To prevent the initial MMU->GCD memory space map synchronization from stripping permissions attributes [which we cannot use in the GCD memory space map, unfortunately], implement the same approach as x86, and ignore SetMemoryAttributes() calls during the time SyncCacheConfig() is in progress. This is a horrible hack, but is currently the only way we can implement strict permissions on arbitrary memory regions [as opposed to PE/COFF text/data sections only] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Jiewen Yao --- ArmPkg/Drivers/CpuDxe/CpuDxe.c | 3 +++ ArmPkg/Drivers/CpuDxe/CpuDxe.h | 1 + ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c | 4 ++++ 3 files changed, 8 insertions(+) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.c b/ArmPkg/Drivers/CpuDxe/CpuDxe.c index 5aa5b874144a..1955d1dece03 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.c +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.c @@ -17,6 +17,7 @@ #include +BOOLEAN gIsFlushingGCD; /** This function flushes the range of addresses from Start to Start+Length @@ -261,7 +262,9 @@ CpuDxeInitialize ( // and that calls EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes, so this code needs to go // after the protocol is installed // + gIsFlushingGCD = TRUE; SyncCacheConfig (&mCpu); + gIsFlushingGCD = FALSE; // If the platform is a MPCore system then install the Configuration Table describing the // secondary core states diff --git a/ArmPkg/Drivers/CpuDxe/CpuDxe.h b/ArmPkg/Drivers/CpuDxe/CpuDxe.h index a00fc3064362..085e4cab2921 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuDxe.h +++ b/ArmPkg/Drivers/CpuDxe/CpuDxe.h @@ -37,6 +37,7 @@ #include #include +extern BOOLEAN gIsFlushingGCD; /** This function registers and enables the handler specified by InterruptHandler for a processor diff --git a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c index ebe593d1c325..6dfec7e55888 100644 --- a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c +++ b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c @@ -188,6 +188,10 @@ CpuSetMemoryAttributes ( UINTN RegionLength; UINTN RegionArmAttributes; + if (gIsFlushingGCD) { + return EFI_SUCCESS; + } + if ((BaseAddress & (SIZE_4KB - 1)) != 0) { // Minimum granularity is SIZE_4KB (4KB on ARM) DEBUG ((EFI_D_PAGE, "CpuSetMemoryAttributes(%lx, %lx, %lx): Minimum ganularity is SIZE_4KB\n", BaseAddress, Length, EfiAttributes)); From patchwork Sun Feb 26 18:30:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94531 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp566254qgi; Sun, 26 Feb 2017 10:30:41 -0800 (PST) X-Received: by 10.98.137.152 with SMTP id n24mr9400518pfk.43.1488133841057; Sun, 26 Feb 2017 10:30:41 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id 7si13110939pfj.170.2017.02.26.10.30.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Feb 2017 10:30:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A49048212B; Sun, 26 Feb 2017 10:30:40 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x232.google.com (mail-wm0-x232.google.com [IPv6:2a00:1450:400c:c09::232]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id CBAA38212B for ; Sun, 26 Feb 2017 10:30:38 -0800 (PST) Received: by mail-wm0-x232.google.com with SMTP id 196so15075064wmm.1 for ; Sun, 26 Feb 2017 10:30:38 -0800 (PST) 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=XVg5C3+o4/fR4e4gaC4Bjpv4JB1mS+5YqUZt4czq1OA=; b=fSNhJeCs7szxrb6btdZ40Se7NP7SNMBeOPQRidpOBA9vLem/ErHeu9aBpr13vdAE9W IW6Elp9GZ0qgjHMXFcnnOKwO5AGrlBmw6mBbAfLba5QZr2qM0mFNNAIpnR7djaFFBFCK TEVSJ3llXDs3zxAIEJanTFjROqyWjq/c+Cypg= 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=XVg5C3+o4/fR4e4gaC4Bjpv4JB1mS+5YqUZt4czq1OA=; b=koccGgxGZlfNi1EW9JynLO3wqqXiSJlAUlZiMrPm1RR1aKBjYTRrR8bqXTdtrz1zJU 4XSbCK7uEBC8EK0V+p25uoNqHXd48OSAhLRujdKbN8ixvwEdsCQPR45sFj79F+tDLaeI nOSvENxlYsf9fgcwJ3R8B5OSBgigAV7fFJ/MHv24AdTdWJtPG2r8S39aKKJDLwWZ/LbU Zw/2uNyjROIQRaC6segmffdrSMaAvldEg55fnOqk/lfu0M9ZELNFL88r6FCyyr3k6Wy2 EncxLMyKlgiIizTD1yb71PcK2CkOuFkYT1Pc9/AKJxsxATVUCra+J6lP9YLAhXt9glRx Eprw== X-Gm-Message-State: AMke39n7j86b3XIfFI64wnI8SJDTcIOwYo1mzOG+RYI2+9eO5ruYLR4HtXACQC+yytXwnts8 X-Received: by 10.28.52.19 with SMTP id b19mr11114221wma.134.1488133837417; Sun, 26 Feb 2017 10:30:37 -0800 (PST) Received: from localhost.localdomain ([105.149.201.216]) by smtp.gmail.com with ESMTPSA id s103sm4499474wrc.6.2017.02.26.10.30.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 26 Feb 2017 10:30:36 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, jiewen.yao@intel.com, leif.lindholm@linaro.org Date: Sun, 26 Feb 2017 18:30:01 +0000 Message-Id: <1488133805-4773-3-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 2/6] MdeModulePkg/PeiCore: allocate BootServicesCode memory for PE/COFF images X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: feng.tian@intel.com, Ard Biesheuvel , afish@apple.com, liming.gao@Intel.com, michael.d.kinney@intel.com, lersek@redhat.com, star.zeng@intel.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Ensure that any memory allocated for PE/COFF images is identifiable as a boot services code region, so that we know it requires its executable permissions to be preserved when we tighten mapping permissions later on. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel Reviewed-by: Jiewen Yao --- MdeModulePkg/Core/Pei/Image/Image.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index d659de8b3e64..8cc9ed93e9b6 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -453,12 +453,16 @@ LoadAndRelocatePeCoffImage ( // // The PEIM is not assiged valid address, try to allocate page to load it. // - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize)); + Status = PeiServicesAllocatePages (EfiBootServicesCode, + EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize), + &ImageContext.ImageAddress); } } else { - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize)); + Status = PeiServicesAllocatePages (EfiBootServicesCode, + EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize), + &ImageContext.ImageAddress); } - if (ImageContext.ImageAddress != 0) { + if (!EFI_ERROR (Status)) { // // Adjust the Image Address to make sure it is section alignment. // From patchwork Sun Feb 26 18:30:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94532 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp566268qgi; Sun, 26 Feb 2017 10:30:43 -0800 (PST) X-Received: by 10.99.177.6 with SMTP id r6mr16291206pgf.61.1488133843292; Sun, 26 Feb 2017 10:30:43 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id z21si13096995pgh.174.2017.02.26.10.30.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Feb 2017 10:30:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D7AED82133; Sun, 26 Feb 2017 10:30:42 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x229.google.com (mail-wm0-x229.google.com [IPv6:2a00:1450:400c:c09::229]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0CF5182132 for ; Sun, 26 Feb 2017 10:30:42 -0800 (PST) Received: by mail-wm0-x229.google.com with SMTP id v186so47151825wmd.0 for ; Sun, 26 Feb 2017 10:30:41 -0800 (PST) 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=qcOZNdDBcj/rOLhRgmRqZqBwBXFU6G60YZ6vkge9ZP4=; b=HljKC1XgR1uGdf6KrJP68JBxrUjp94s22lE+7Bxd53TeCQWGB8Ouk2o8J+Go5wv4hm B9jpbOfshEceTZEslI9VOMEMPDhlE7JPhSpGIoZBgl0EfPmicq8mBTE0zwNB8a25SAgI QdJEbsItOic/6wAlfqAqiEvySz0Ql42Dp9UTk= 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=qcOZNdDBcj/rOLhRgmRqZqBwBXFU6G60YZ6vkge9ZP4=; b=LdQoSvwbcJpRWNdprPH/FFlBzwaff9WG0R2g1XHTJZD7qlkvcD6xzM9f5feQ9Nmhny rJRb+Y5XbyVn7koLNcBjf1p3YGn5AHXikqxOZQLrqqxmR8isemRvZenLrkkFUFrnXz1J 7MqkpQRoL7HSNixH7hyp+DIA7bUxOYr0lVH5PiMnQboddvplXKagOw9j+Gy6YLcmICg/ zVA1QWZPQuYlmphXIVaU/BQG0a2FBXNoLHgV13y2bcqAnKAdxYcYemz3LyiPRr0vq4bs Z0nzG9AqS/XkTauwO8c19s1zEu8CAkHIiMxG9UY4AkKMKCjV5L79Ycmw/17GL3o4RdBn JYXA== X-Gm-Message-State: AMke39mESlaQyejKMJMs3M4xswsKLYzXvGnPXNy2kSpx6kLauI3OT84dr4p7vSrjA0Fu777C X-Received: by 10.28.46.74 with SMTP id u71mr10104548wmu.136.1488133840528; Sun, 26 Feb 2017 10:30:40 -0800 (PST) Received: from localhost.localdomain ([105.149.201.216]) by smtp.gmail.com with ESMTPSA id s103sm4499474wrc.6.2017.02.26.10.30.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 26 Feb 2017 10:30:39 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, jiewen.yao@intel.com, leif.lindholm@linaro.org Date: Sun, 26 Feb 2017 18:30:02 +0000 Message-Id: <1488133805-4773-4-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 3/6] MdeModulePkg/EbcDxe: use EfiBootServicesCode memory for thunks X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: feng.tian@intel.com, Ard Biesheuvel , afish@apple.com, liming.gao@Intel.com, michael.d.kinney@intel.com, lersek@redhat.com, star.zeng@intel.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" The EBC driver emits thunks for native to EBC calls, which are short instructions sequences that bridge the gap between the native execution environment and the EBC virtual machine. Since these thunks are allocated using MemoryAllocationLib::AllocatePool(), they are emitted into EfiBootServicesData regions, which does not reflect the nature of these thunks accurately, and interferes with strict memory protection policies that map data regions non-executable. So instead, create a new helper EbcAllocatePoolForThunk() that invokes the AllocatePool() boot services directly to allocate EfiBootServicesCode pool memory explicitly, and wire up this helper for the various architecture specific thunk generation routines. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c | 2 +- MdeModulePkg/Universal/EbcDxe/EbcInt.c | 23 ++++++++++++++++++++ MdeModulePkg/Universal/EbcDxe/EbcInt.h | 14 ++++++++++++ MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c | 2 +- MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c | 2 +- MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c | 2 +- 6 files changed, 41 insertions(+), 4 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c index ade47c4d0622..7c13ce12a38b 100644 --- a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c @@ -383,7 +383,7 @@ EbcCreateThunks ( return EFI_INVALID_PARAMETER; } - InstructionBuffer = AllocatePool (sizeof (EBC_INSTRUCTION_BUFFER)); + InstructionBuffer = EbcAllocatePoolForThunk (sizeof (EBC_INSTRUCTION_BUFFER)); if (InstructionBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.c b/MdeModulePkg/Universal/EbcDxe/EbcInt.c index 6fd2aaf5af27..727ba8bcae44 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c @@ -1410,3 +1410,26 @@ EbcVmTestUnsupported ( return EFI_UNSUPPORTED; } +/** + Allocates a buffer of type EfiBootServicesCode. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +EbcAllocatePoolForThunk ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + EFI_STATUS Status; + + Status = gBS->AllocatePool (EfiBootServicesCode, AllocationSize, &Buffer); + if (EFI_ERROR (Status)) { + return NULL; + } + return Buffer; +} diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.h b/MdeModulePkg/Universal/EbcDxe/EbcInt.h index 75017a23e75e..8aa7a4abbd63 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.h +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.h @@ -246,4 +246,18 @@ typedef struct { CR(a, EBC_PROTOCOL_PRIVATE_DATA, EbcProtocol, EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE) +/** + Allocates a buffer of type EfiBootServicesCode. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +EbcAllocatePoolForThunk ( + IN UINTN AllocationSize + ); + #endif // #ifndef _EBC_INT_H_ diff --git a/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c index 8e660b93ad64..a825846f89c3 100644 --- a/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c @@ -484,7 +484,7 @@ EbcCreateThunks ( ThunkSize = sizeof(mInstructionBufferTemplate); - Ptr = AllocatePool (sizeof(mInstructionBufferTemplate)); + Ptr = EbcAllocatePoolForThunk (sizeof(mInstructionBufferTemplate)); if (Ptr == NULL) { return EFI_OUT_OF_RESOURCES; diff --git a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c index 95837cb67865..f99348f181a9 100644 --- a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c @@ -403,7 +403,7 @@ EbcCreateThunks ( // Size = EBC_THUNK_SIZE + EBC_THUNK_ALIGNMENT - 1; ThunkSize = Size; - Ptr = AllocatePool (Size); + Ptr = EbcAllocatePoolForThunk (Size); if (Ptr == NULL) { return EFI_OUT_OF_RESOURCES; diff --git a/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c index 4325e2e52710..33a174917b69 100644 --- a/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c @@ -441,7 +441,7 @@ EbcCreateThunks ( ThunkSize = sizeof(mInstructionBufferTemplate); - Ptr = AllocatePool (sizeof(mInstructionBufferTemplate)); + Ptr = EbcAllocatePoolForThunk (sizeof(mInstructionBufferTemplate)); if (Ptr == NULL) { return EFI_OUT_OF_RESOURCES; From patchwork Sun Feb 26 18:30:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94533 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp566282qgi; Sun, 26 Feb 2017 10:30:46 -0800 (PST) X-Received: by 10.84.198.164 with SMTP id p33mr18743915pld.85.1488133846504; Sun, 26 Feb 2017 10:30:46 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id k126si4967342pfc.110.2017.02.26.10.30.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Feb 2017 10:30:46 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1CC3F82132; Sun, 26 Feb 2017 10:30:46 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x22f.google.com (mail-wm0-x22f.google.com [IPv6:2a00:1450:400c:c09::22f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 159C582101 for ; Sun, 26 Feb 2017 10:30:45 -0800 (PST) Received: by mail-wm0-x22f.google.com with SMTP id v77so46916493wmv.1 for ; Sun, 26 Feb 2017 10:30:45 -0800 (PST) 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=CTgLr8j5GyFzE9yopzHD+EE4qc7FWQ0xFUNPbEhDlB4=; b=jmIbt36CSpJrWYwXByi0K6om0n8pNZeJ4Y6LRTJE0x+v5K3jiaRZ9qvdmWZWrgyLfP WmucBCLtvdN8g/yMBwrNQrgAo0ZnITnA5nkOPOxLOovtndO0V6hqWGBEmcTNnz5j8RFy sbkwSuvh46nlV38ufDhNPGzRkQq+KyXxUSUMg= 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=CTgLr8j5GyFzE9yopzHD+EE4qc7FWQ0xFUNPbEhDlB4=; b=OhscTH724KPuCpTBIF91Q/C691Fm8/TmFT1anYlTsbBtcGioPJ6OUTHx8llwj819EE Myaq8D5iP2o1FAE6mBDjhXWjmDSzsYdVbuYKTZtWrkbRWr+A1WlKkBZ5/q7bK9eHmrSu Hv3sb0IFlGXciy2Ln8FYU5IRQUdsQVyZEzRYVdlgZBjC6xoya7HTbRs+lp60Twmf4s8E Gp+re0YXYUY4C9m3P7Vb0vXth77fYPCrRTmoixMsGkAn/b8f4fD0s0CEv2Itlwv3IQH2 UpNckrwRamgxjaXDFGdj3oz3n1P1I7yjabIASfR7RE+M8Jb0qX3mpIlCmdAMWGOIzYST Y7TQ== X-Gm-Message-State: AMke39lROnxrLVkx9OWQ1EClicDECP5fr4JHulw5m5qxgkUfj0OyW+xgJ+5A6e9IRBWzc7kL X-Received: by 10.28.66.11 with SMTP id p11mr11630394wma.38.1488133843544; Sun, 26 Feb 2017 10:30:43 -0800 (PST) Received: from localhost.localdomain ([105.149.201.216]) by smtp.gmail.com with ESMTPSA id s103sm4499474wrc.6.2017.02.26.10.30.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 26 Feb 2017 10:30:42 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, jiewen.yao@intel.com, leif.lindholm@linaro.org Date: Sun, 26 Feb 2017 18:30:03 +0000 Message-Id: <1488133805-4773-5-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 4/6] MdeModulePkg/DxeCore: use separate lock for pool allocations X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: feng.tian@intel.com, Ard Biesheuvel , afish@apple.com, liming.gao@Intel.com, michael.d.kinney@intel.com, lersek@redhat.com, star.zeng@intel.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" In preparation of adding memory permission attribute management to the pool allocator, split off the locking of the pool metadata into a separate lock. This is an improvement in itself, given that pool allocation can only interfere with the page allocation bookkeeping if pool pages are allocated or released. But it is also required to ensure that the permission attribute management does not deadlock, given that it may trigger page table splits leading to additional page tables being allocated. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Core/Dxe/Mem/Pool.c | 53 ++++++++++++++++---- 1 file changed, 43 insertions(+), 10 deletions(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Signed-off-by: Ard Biesheuvel diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c index 7afd2d312c1d..410615e0dee9 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c +++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c @@ -15,6 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "DxeMain.h" #include "Imem.h" +STATIC EFI_LOCK mPoolMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); + #define POOL_FREE_SIGNATURE SIGNATURE_32('p','f','r','0') typedef struct { UINT32 Signature; @@ -239,13 +241,13 @@ CoreInternalAllocatePool ( // // Acquire the memory lock and make the allocation // - Status = CoreAcquireLockOrFail (&gMemoryLock); + Status = CoreAcquireLockOrFail (&mPoolMemoryLock); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } *Buffer = CoreAllocatePoolI (PoolType, Size); - CoreReleaseMemoryLock (); + CoreReleaseLock (&mPoolMemoryLock); return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES; } @@ -289,6 +291,23 @@ CoreAllocatePool ( return Status; } +STATIC +VOID * +CoreAllocatePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN NoPages, + IN UINTN Granularity + ) +{ + VOID *Buffer; + + CoreAcquireMemoryLock (); + Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity); + CoreReleaseMemoryLock (); + + return Buffer; +} + /** Internal function to allocate pool of a particular type. Caller must have the memory lock held @@ -317,7 +336,7 @@ CoreAllocatePoolI ( UINTN NoPages; UINTN Granularity; - ASSERT_LOCKED (&gMemoryLock); + ASSERT_LOCKED (&mPoolMemoryLock); if (PoolType == EfiACPIReclaimMemory || PoolType == EfiACPIMemoryNVS || @@ -355,7 +374,7 @@ CoreAllocatePoolI ( if (Index >= SIZE_TO_LIST (Granularity)) { NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1; NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1); - Head = CoreAllocatePoolPages (PoolType, NoPages, Granularity); + Head = CoreAllocatePoolPagesI (PoolType, NoPages, Granularity); goto Done; } @@ -383,7 +402,7 @@ CoreAllocatePoolI ( // // Get another page // - NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (Granularity), Granularity); + NewPage = CoreAllocatePoolPagesI (PoolType, EFI_SIZE_TO_PAGES (Granularity), Granularity); if (NewPage == NULL) { goto Done; } @@ -486,9 +505,9 @@ CoreInternalFreePool ( return EFI_INVALID_PARAMETER; } - CoreAcquireMemoryLock (); + CoreAcquireLock (&mPoolMemoryLock); Status = CoreFreePoolI (Buffer, PoolType); - CoreReleaseMemoryLock (); + CoreReleaseLock (&mPoolMemoryLock); return Status; } @@ -525,6 +544,19 @@ CoreFreePool ( return Status; } +STATIC +VOID +CoreFreePoolPagesI ( + IN EFI_MEMORY_TYPE PoolType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ) +{ + CoreAcquireMemoryLock (); + CoreFreePoolPages (Memory, NoPages); + CoreReleaseMemoryLock (); +} + /** Internal function to free a pool entry. Caller must have the memory lock held @@ -573,7 +605,7 @@ CoreFreePoolI ( // ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE); ASSERT (Head->Size == Tail->Size); - ASSERT_LOCKED (&gMemoryLock); + ASSERT_LOCKED (&mPoolMemoryLock); if (Tail->Signature != POOL_TAIL_SIGNATURE) { return EFI_INVALID_PARAMETER; @@ -624,7 +656,7 @@ CoreFreePoolI ( // NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1; NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1); - CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages); + CoreFreePoolPagesI (Pool->MemoryType, (EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages); } else { @@ -680,7 +712,8 @@ CoreFreePoolI ( // // Free the page // - CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (Granularity)); + CoreFreePoolPagesI (Pool->MemoryType, (EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, + EFI_SIZE_TO_PAGES (Granularity)); } } } From patchwork Sun Feb 26 18:30:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94534 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp566295qgi; Sun, 26 Feb 2017 10:30:49 -0800 (PST) X-Received: by 10.84.138.3 with SMTP id 3mr18713913plo.94.1488133849695; Sun, 26 Feb 2017 10:30:49 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id p1si13122111pld.270.2017.02.26.10.30.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Feb 2017 10:30:49 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4D2CF82139; Sun, 26 Feb 2017 10:30:49 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x235.google.com (mail-wm0-x235.google.com [IPv6:2a00:1450:400c:c09::235]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 4651E82101 for ; Sun, 26 Feb 2017 10:30:48 -0800 (PST) Received: by mail-wm0-x235.google.com with SMTP id u199so3625762wmd.1 for ; Sun, 26 Feb 2017 10:30:48 -0800 (PST) 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=nCdhTcCKbliJdQVn0VcXSzR8JrRq35TZZR1qi7UOEpE=; b=ThGRyh2UtYxnsiYq37U6Hpr95woUs+aT3HSw4zTM+f1sMRGHVnJQYc0V234+Vq56uX TrybrMH82jjOgbVXFLRMMKVk8r7HPdd6v7StniefAAcslQwjudNumyCp0izIMa937muC BTSmLG7Tagbwdb2HmFaiexkslB7/GgYQ6O4to= 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=nCdhTcCKbliJdQVn0VcXSzR8JrRq35TZZR1qi7UOEpE=; b=uXfcJhSytl/ItiZImQJ1YRux0I/t+c2nGwdu8TLqvg8DVtN7YhiW0oHBKm5ab6hLD4 GO9FjFu9/igY/idC5zhSy8VNudjIQcWfw8xcnsHqZFBOdNEAYed0jD73JP/kb1FOojg/ z54Uec/kUxNiygtU5y7y+YE4fKYi6OAWqkaYXs/Tlbcq9AE4ZPGBlCzTCgKjezH8TV5b jAtGibDPZmzaS1qdjpop1gmuiARWw9g0uZCpMFlnLTJGKZfNUBfakcpFWo6k5ONlQpfc 3Zdnr3EP9FLL5sRabrVNu7shBUek1qwCbZz+zc3kd7IQah2Vqazk18xBLl4vJj/6/1QN jeYA== X-Gm-Message-State: AMke39mOxfICZwjW+YIeswGxb+WikbXBkqwVRRWsn2OzlHwYMTyPL9jk8Tb3AXZD3SlYIaTY X-Received: by 10.28.144.135 with SMTP id s129mr10451360wmd.18.1488133846776; Sun, 26 Feb 2017 10:30:46 -0800 (PST) Received: from localhost.localdomain ([105.149.201.216]) by smtp.gmail.com with ESMTPSA id s103sm4499474wrc.6.2017.02.26.10.30.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 26 Feb 2017 10:30:45 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, jiewen.yao@intel.com, leif.lindholm@linaro.org Date: Sun, 26 Feb 2017 18:30:04 +0000 Message-Id: <1488133805-4773-6-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 5/6] MdeModulePkg: define PCD for DXE memory protection policy X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: feng.tian@intel.com, Ard Biesheuvel , afish@apple.com, liming.gao@Intel.com, michael.d.kinney@intel.com, lersek@redhat.com, star.zeng@intel.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" Define a new fixed/patchable PCD that sets the DXE memory protection policy: its primary use is to define which memory types should have their executable permissions removed. Combined with the image protection policy, this can be used to implement a strict W^X policy, i.e.. a policy where no regions exist that are both executable and writable at the same time. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- MdeModulePkg/MdeModulePkg.dec | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 426634fbbd4d..fb6a39c9e354 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -1107,6 +1107,37 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] # @ValidRange 0x80000002 | 0x00000000 - 0x0000001F gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000002|UINT32|0x00001047 + ## Set DXE memory protection policy. The policy is bitwise. + # If a bit is set, memory regions of the associated type will be mapped + # non-executable.

+ # + # Below is bit mask for this PCD: (Order is same as UEFI spec)
+ # EfiReservedMemoryType 0x0001
+ # EfiLoaderCode 0x0002
+ # EfiLoaderData 0x0004
+ # EfiBootServicesCode 0x0008
+ # EfiBootServicesData 0x0010
+ # EfiRuntimeServicesCode 0x0020
+ # EfiRuntimeServicesData 0x0040
+ # EfiConventionalMemory 0x0080
+ # EfiUnusableMemory 0x0100
+ # EfiACPIReclaimMemory 0x0200
+ # EfiACPIMemoryNVS 0x0400
+ # EfiMemoryMappedIO 0x0800
+ # EfiMemoryMappedIOPortSpace 0x1000
+ # EfiPalCode 0x2000
+ # EfiPersistentMemory 0x4000
+ # OEM Reserved 0x4000000000000000
+ # OS Reserved 0x8000000000000000
+ # + # NOTE: User must NOT set NX protection for EfiLoaderCode / EfiBootServicesCode / EfiRuntimeServicesCode.
+ # + # e.g. 0x7FD5 can be used for all memory except Code.
+ # e.g. 0x7BD4 can be used for all memory except Code and ACPINVS/Reserved.
+ # + # @Prompt Set DXE memory protection policy. + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeMemoryProtectionPolicy|0x0000000|UINT64|0x00001048 + ## PCI Serial Device Info. It is an array of Device, Function, and Power Management # information that describes the path that contains zero or more PCI to PCI briges # followed by a PCI serial device. Each array entry is 4-bytes in length. The From patchwork Sun Feb 26 18:30:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 94535 Delivered-To: patch@linaro.org Received: by 10.140.20.113 with SMTP id 104csp566319qgi; Sun, 26 Feb 2017 10:30:53 -0800 (PST) X-Received: by 10.84.218.204 with SMTP id g12mr18653207plm.78.1488133853922; Sun, 26 Feb 2017 10:30:53 -0800 (PST) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id n64si13126999pgn.27.2017.02.26.10.30.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Feb 2017 10:30:53 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 7E3FE82144; Sun, 26 Feb 2017 10:30:53 -0800 (PST) X-Original-To: edk2-devel@lists.01.org Delivered-To: edk2-devel@lists.01.org Received: from mail-wm0-x233.google.com (mail-wm0-x233.google.com [IPv6:2a00:1450:400c:c09::233]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 6251382101 for ; Sun, 26 Feb 2017 10:30:51 -0800 (PST) Received: by mail-wm0-x233.google.com with SMTP id v77so47559412wmv.0 for ; Sun, 26 Feb 2017 10:30:51 -0800 (PST) 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=a79GOy+joRMlSezljz6Ft3qZZmVq4lf0nRsdC2EY9pw=; b=giaNgZOT+wl571Wc31yhgfQpb8mMtssrsHfZqZiITUAshaQtA72/V/2YldAXJoUAlH 6gViLSu9y+TkwLgAOkNFz45NJExxugGVtEetZJ81sf5CiV0FB4R5HVMEHT0pidCyt0WW 3/BokHTY09c6wHaWbLARFXZWVYMhnq2qDX2sI= 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=a79GOy+joRMlSezljz6Ft3qZZmVq4lf0nRsdC2EY9pw=; b=gT395NdDaEvhxGuk8xQ4NqXFix/ju9jHfPxPwRfyzqjUcA6unPKYUNBYA778iKmLUO vlYt4GOH+oTC3w7lf0axbTgkonP7xJJMMo29Kjda1lMB/CNnkZaYba1YKG+n3+/EfgMO 695BQqk4U7xnO2jvtYoK7QhwvOETYyzTDGTgBGcvMYgfHMDNLQT8FhJY16bzE2khgi6h Vb1+TanJOzQovjb2c62DLu/KaspCJR+cq+3rlEBxPXZ2TttbcRiPLZYn6FpjKh6p8ec/ aqJ1P2iEZ2SVtIGhVa/Vfg69gHKZkoIPGYwBID5KcNdQlaP1ebojPDIjgGzRYmm7TZvg jW9g== X-Gm-Message-State: AMke39l/yKQD6OkuAV8BZi7T53uijU7znXF0kRymrEnblOVblkk/dCPnpzGH7L8VR60sBoTZ X-Received: by 10.28.28.74 with SMTP id c71mr6016879wmc.9.1488133849748; Sun, 26 Feb 2017 10:30:49 -0800 (PST) Received: from localhost.localdomain ([105.149.201.216]) by smtp.gmail.com with ESMTPSA id s103sm4499474wrc.6.2017.02.26.10.30.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 26 Feb 2017 10:30:48 -0800 (PST) From: Ard Biesheuvel To: edk2-devel@lists.01.org, jiewen.yao@intel.com, leif.lindholm@linaro.org Date: Sun, 26 Feb 2017 18:30:05 +0000 Message-Id: <1488133805-4773-7-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> References: <1488133805-4773-1-git-send-email-ard.biesheuvel@linaro.org> Subject: [edk2] [PATCH v3 6/6] MdeModulePkg/DxeCore: implement memory protection policy X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: feng.tian@intel.com, Ard Biesheuvel , afish@apple.com, liming.gao@Intel.com, michael.d.kinney@intel.com, lersek@redhat.com, star.zeng@intel.com MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" This implements a DXE memory protection policy that ensure that regions that don't require executable permissions are mapped with the non-exec attribute set. First of all, it iterates over all entries in the UEFI memory map, and removes executable permissions according to the configured DXE memory protection policy, as recorded in PcdDxeMemoryProtectionPolicy. Secondly, it sets or clears the non-executable attribute when allocating or freeing pages, both for page based or pool based allocations. Note that this complements the image protection facility, which applies strict permissions to BootServicesCode/RuntimeServicesCode regions when the section alignment allows it. The memory protection configured by this patch operates on non-code regions only. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- MdeModulePkg/Core/Dxe/DxeMain.h | 24 ++ MdeModulePkg/Core/Dxe/DxeMain.inf | 1 + MdeModulePkg/Core/Dxe/Mem/Page.c | 4 + MdeModulePkg/Core/Dxe/Mem/Pool.c | 7 + MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 306 +++++++++++++++++++- 5 files changed, 341 insertions(+), 1 deletion(-) -- 2.7.4 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h index b14be9a74d8e..5668c1f2d648 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ b/MdeModulePkg/Core/Dxe/DxeMain.h @@ -2949,4 +2949,28 @@ MemoryProtectionExitBootServicesCallback ( VOID ); +/** + Manage memory permission attributes on a memory range, according to the + configured DXE memory protection policy. + + @param OldType The old memory type of the range + @param NewType The new memory type of the range + @param Memory The base address of the range + @param Length The size of the range (in bytes) + + @return EFI_SUCCESS If the the CPU arch protocol is not installed yet + @return EFI_SUCCESS If no DXE memory protection policy has been configured + @return EFI_SUCCESS If OldType and NewType use the same permission attributes + @return other Return value of gCpu->SetMemoryAttributes() + +**/ +EFI_STATUS +EFIAPI +ApplyMemoryProtectionPolicy ( + IN EFI_MEMORY_TYPE OldType, + IN EFI_MEMORY_TYPE NewType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINT64 Length + ); + #endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 371e91cb0d7e..30d5984f7c1f 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -191,6 +191,7 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES # [Hob] # RESOURCE_DESCRIPTOR ## CONSUMES diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index bda4f6397e91..86874906de58 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -1344,6 +1344,8 @@ CoreAllocatePages ( NULL ); InstallMemoryAttributesTableOnMemoryAllocation (MemoryType); + ApplyMemoryProtectionPolicy (EfiConventionalMemory, MemoryType, *Memory, + EFI_PAGES_TO_SIZE (NumberOfPages)); } return Status; } @@ -1460,6 +1462,8 @@ CoreFreePages ( NULL ); InstallMemoryAttributesTableOnMemoryAllocation (MemoryType); + ApplyMemoryProtectionPolicy (MemoryType, EfiConventionalMemory, Memory, + EFI_PAGES_TO_SIZE (NumberOfPages)); } return Status; } diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c index 410615e0dee9..63b9983b88b5 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c +++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c @@ -305,6 +305,10 @@ CoreAllocatePoolPagesI ( Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity); CoreReleaseMemoryLock (); + if (Buffer != NULL) { + ApplyMemoryProtectionPolicy (EfiConventionalMemory, PoolType, + (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (NoPages)); + } return Buffer; } @@ -555,6 +559,9 @@ CoreFreePoolPagesI ( CoreAcquireMemoryLock (); CoreFreePoolPages (Memory, NoPages); CoreReleaseMemoryLock (); + + ApplyMemoryProtectionPolicy (PoolType, EfiConventionalMemory, + (EFI_PHYSICAL_ADDRESS)(UINTN)Memory, EFI_PAGES_TO_SIZE (NoPages)); } /** diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c index 46d88463d417..f2a69a3d0df9 100644 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c @@ -64,6 +64,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define DO_NOT_PROTECT 0x00000000 #define PROTECT_IF_ALIGNED_ELSE_ALLOW 0x00000001 +#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 +#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 + +#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) + UINT32 mImageProtectionPolicy; /** @@ -647,6 +653,210 @@ UnprotectUefiImage ( } /** + Return the EFI memory permission attribute associated with memory + type 'Type' under the configured DXE memory protection policy. +**/ +STATIC +UINT64 +GetPermissionAttributeForMemoryType ( + IN EFI_MEMORY_TYPE MemoryType + ) +{ + UINT64 TestBit; + + if ((UINT32) MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { + TestBit = BIT63; + } else if ((UINT32) MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { + TestBit = BIT62; + } else { + TestBit = LShiftU64 (1, MemoryType); + } + + if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) != 0) { + return EFI_MEMORY_XP; + } else { + return 0; + } +} + +/** + Sort memory map entries based upon PhysicalStart, from low to high. + + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. + @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +SortMemoryMap ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + EFI_MEMORY_DESCRIPTOR TempMemoryMap; + + MemoryMapEntry = MemoryMap; + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); + while (MemoryMapEntry < MemoryMapEnd) { + while (NextMemoryMapEntry < MemoryMapEnd) { + if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) { + CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); + CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); + CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof(EFI_MEMORY_DESCRIPTOR)); + } + + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + } + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + } +} + +/** + Merge adjacent memory map entries if they use the same memory protection policy + + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the current memory map. On output, + it is the size of new memory map after merge. + @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +MergeMemoryMapForProtectionPolicy ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN OUT UINTN *MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + UINT64 MemoryBlockLength; + EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; + UINT64 Attributes; + + SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize); + + MemoryMapEntry = MemoryMap; + NewMemoryMapEntry = MemoryMap; + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + *MemoryMapSize); + while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { + CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + + do { + MemoryBlockLength = (UINT64) (EFI_PAGES_TO_SIZE((UINTN)MemoryMapEntry->NumberOfPages)); + Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type); + + if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && + Attributes == GetPermissionAttributeForMemoryType (NextMemoryMapEntry->Type) && + ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) { + MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + if (NewMemoryMapEntry != MemoryMapEntry) { + NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + } + + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + continue; + } else { + MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + break; + } + } while (TRUE); + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); + } + + *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; + + return ; +} + + +/** + Remove exec permissions from all regions whose type is identified by + PcdDxeNxMemoryProtectionPolicy +**/ +STATIC +VOID +InitializeDxeNxMemoryProtectionPolicy ( + VOID + ) +{ + UINTN MemoryMapSize; + UINTN MapKey; + UINTN DescriptorSize; + UINT32 DescriptorVersion; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + EFI_STATUS Status; + UINT64 Attributes; + + // + // Get the EFI memory map. + // + MemoryMapSize = 0; + MemoryMap = NULL; + + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + do { + MemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (MemoryMapSize); + ASSERT (MemoryMap != NULL); + Status = gBS->GetMemoryMap ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + if (EFI_ERROR (Status)) { + FreePool (MemoryMap); + } + } while (Status == EFI_BUFFER_TOO_SMALL); + ASSERT_EFI_ERROR (Status); + + DEBUG((DEBUG_ERROR, "%a: removing exec permissions from memory regions\n", + __FUNCTION__)); + + MergeMemoryMapForProtectionPolicy (MemoryMap, &MemoryMapSize, DescriptorSize); + + MemoryMapEntry = MemoryMap; + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); + while ((UINTN) MemoryMapEntry < (UINTN) MemoryMapEnd) { + + Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type); + if (Attributes != 0) { + SetUefiImageMemoryAttributes ( + MemoryMapEntry->PhysicalStart, + EFI_PAGES_TO_SIZE (MemoryMapEntry->NumberOfPages), + Attributes); + } + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + } + FreePool (MemoryMap); +} + + +/** A notification for CPU_ARCH protocol. @param[in] Event Event whose notification function is being invoked. @@ -674,6 +884,17 @@ MemoryProtectionCpuArchProtocolNotify ( return; } + // + // Apply the memory protection policy on non-BScode/RTcode regions. + // + if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) { + InitializeDxeNxMemoryProtectionPolicy (); + } + + if (mImageProtectionPolicy == 0) { + return; + } + Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiLoadedImageProtocolGuid, @@ -753,7 +974,7 @@ CoreInitializeMemoryProtection ( mImageProtectionPolicy = PcdGet32(PcdImageProtectionPolicy); - if (mImageProtectionPolicy != 0) { + if (mImageProtectionPolicy != 0 || PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) { Status = CoreCreateEvent ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, @@ -775,3 +996,86 @@ CoreInitializeMemoryProtection ( } return ; } + +STATIC +BOOLEAN +IsInSmm ( + VOID + ) +{ + BOOLEAN InSmm; + + InSmm = FALSE; + if (gSmmBase2 != NULL) { + gSmmBase2->InSmm (gSmmBase2, &InSmm); + } + return InSmm; +} + +/** + Manage memory permission attributes on a memory range, according to the + configured DXE memory protection policy. + + @param OldType The old memory type of the range + @param NewType The new memory type of the range + @param Memory The base address of the range + @param Length The size of the range (in bytes) + + @return EFI_SUCCESS If we are executing in SMM mode. No permission attributes + are updated in this case + @return EFI_SUCCESS If the the CPU arch protocol is not installed yet + @return EFI_SUCCESS If no DXE memory protection policy has been configured + @return EFI_SUCCESS If OldType and NewType use the same permission attributes + @return other Return value of gCpu->SetMemoryAttributes() + +**/ +EFI_STATUS +EFIAPI +ApplyMemoryProtectionPolicy ( + IN EFI_MEMORY_TYPE OldType, + IN EFI_MEMORY_TYPE NewType, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINT64 Length + ) +{ + UINT64 OldAttributes; + UINT64 NewAttributes; + + // + // The policy configured in PcdDxeNxMemoryProtectionPolicy + // does not apply to allocations performed in SMM mode. + // + if (IsInSmm ()) { + return EFI_SUCCESS; + } + + // + // If the CPU arch protocol is not installed yet, we cannot manage memory + // permission attributes, and it is the job of the driver that installs this + // protocol to set the permissions on existing allocations. + // + if (gCpu == NULL) { + return EFI_SUCCESS; + } + + // + // Check if a DXE memory protection policy has been configured + // + if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) == 0) { + return EFI_SUCCESS; + } + + // + // Update the executable permissions according to the DXE memory + // protection policy, but only if the policy is different between + // the old and the new type. + // + OldAttributes = GetPermissionAttributeForMemoryType (OldType); + NewAttributes = GetPermissionAttributeForMemoryType (NewType); + + if (OldAttributes == NewAttributes) { + return EFI_SUCCESS; + } + + return gCpu->SetMemoryAttributes (gCpu, Memory, Length, NewAttributes); +}