From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by mx.groups.io with SMTP id smtpd.web11.16972.1676301511033450538 for ; Mon, 13 Feb 2023 07:18:31 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rzxnRCN5; spf=pass (domain: kernel.org, ip: 145.40.68.75, mailfrom: ardb@kernel.org) 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 ams.source.kernel.org (Postfix) with ESMTPS id 3B5F8B8125B; Mon, 13 Feb 2023 15:18:29 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E52ADC433EF; Mon, 13 Feb 2023 15:18:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1676301507; bh=Q0kfA/dtVc9gZNTtjJ2Sur2FC2KRaDq0urHQFd0uJf4=; h=From:To:Cc:Subject:Date:From; b=rzxnRCN5tMqHr1Pte9DbLf8DzGL47Srw8a8SAg/TMspl1VsxJB6pEo5bGoQdv4s+z mHxelbO/IP9/RSwu4x2ISfrrOT0+5PN4YRTRmnKOPQWhDPaBU/Thyz9ZdgJJoj2pla MIoc3sNpdtkesEd8bJmg241ly7vBNjP3oc+i7mTzwEwvWg3jAeJOHhsNSL35pHP8L4 ZtTNFWFS8hL3mqrQxJQBomF6Ov4XZDUwcuFTwyCILGIbrAjSjkRsZnks7uLIUNsxrH uCh/3WP+rC1FrQ7OFTfUkb3QIhHn0DipRYqhrpIi6JS77uf3Le8yzZYeel2i2U7v0n N2qeSjXsNeBmw== From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Michael Kinney , Liming Gao , Jiewen Yao , Michael Kubacki , Sean Brogan , Rebecca Cran , Leif Lindholm , Sami Mujawar , Taylor Beebe , Matthew Garrett , Peter Jones , Kees Cook Subject: [RFC 00/13] Hardware enforced W^X memory protections Date: Mon, 13 Feb 2023 16:17:57 +0100 Message-Id: <20230213151810.2301480-1-ardb@kernel.org> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable The ARM architecture has an interesting feature in its virtual memory=0D controls called 'WXN', which puts the MMU in a mode where all mappings=0D of memory that are writable are implicitly non-executable as well.=0D =0D While EDK2 implements a couple of memory protection features already, in=0D some places it still relies fundamentally on mappings that are both=0D writable and executable at the same time, which is not great from a=0D robustness and code safety point of view.=0D =0D This series is a proof-of-concept for ArmVirtQemu that addresses each of=0D those issues, allowing it to boot into the OS (Linux) successfully with=0D the WXN control enabled.=0D =0D The following issues are being addressed:=0D - the flash region must be mapped read-only explicitly, so that its code=0D is executable=0D - the DXE IPL must not run shadowed so it executes in place from the=0D executable mapping of the FV (and PEIM shadowing must be off in=0D general)=0D - the DXE IPL must map the DXE core code region read-only explicitly so=0D it can execute=0D - the DXE core must be equipped with a preliminary version of the=0D SetMemoryAttributes member of the CPU arch protocol so that it can=0D manipulate memory permissions before the CPU arch protocol driver is=0D dispatched=0D - need to use XP mappings for all DRAM regions out of reset - this is=0D to avoid unbounded recursion in the page table handling code, which=0D may now be called before the CPU arch protocol driver remaps all=0D unused regions with XP attributes=0D - limit the memory regions that are remapped writable+executable during=0D ExitBootServices() to those pages that are actually subject to=0D relocation fixups=0D - ensure that AArch64 runtime DXE driver images do not carry code and=0D relocatable quantities in the same 4k page, so that clearing the RO=0D bit does not remove its executable permissions=0D =0D (patch #1 is preparatory cleanup and not relevant to the above)=0D =0D Cc: Michael Kinney =0D Cc: Liming Gao =0D Cc: Jiewen Yao =0D Cc: Michael Kubacki =0D Cc: Sean Brogan =0D Cc: Rebecca Cran =0D Cc: Leif Lindholm =0D Cc: Sami Mujawar =0D Cc: Taylor Beebe =0D Cc: Matthew Garrett =0D Cc: Peter Jones =0D Cc: Kees Cook =0D =0D Ard Biesheuvel (13):=0D ArmPkg/Mmu: Remove handling of NONSECURE memory regions=0D ArmPkg/ArmMmuLib: Introduce region types for RO/XP WB cached memory=0D MdePkg/BasePeCoffLib: Add API to keep track of relocation range=0D MdeModulePkg/DxeIpl: Avoid shadowing IPL PEIM by default=0D MdeModulePkg/DxeIpl AARCH64: Remap DXE core code section before launch=0D MdeModulePkg/DxeCore: Reduce range of W+X remaps at EBS time=0D MdeModulePkg/DxeCore: Permit preliminary CPU arch fallback=0D ArmPkg: Implement ArmSetMemoryOverrideLib=0D ArmVirtPkg/ArmVirtQemu: Use XP memory mappings by default=0D ArmVirtPkg/ArmVirtQemu: Use PEI flavor of ArmMmuLib for all PEIMs=0D ArmVirtPkg/ArmVirtQemu: Use read-only memory region type for code=0D flash=0D BaseTools/GccBase AARCH64: Avoid page sharing between code and data=0D ArmVirtPkg/ArmVirtQemu: Enable hardware enforced W^X memory=0D permissions=0D =0D ArmPkg/Include/Chipset/ArmV7Mmu.h | 51 ++= +++-------=0D ArmPkg/Include/Library/ArmLib.h | 17 ++= --=0D ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 34 ++= +++---=0D ArmPkg/Library/ArmMmuLib/Arm/ArmMmuLibCore.c | 49 ++= ++++------=0D ArmPkg/Library/ArmSetMemoryOverrideLib/ArmSetMemoryOverrideLib.c | 56 ++= +++++++++++=0D ArmPkg/Library/ArmSetMemoryOverrideLib/ArmSetMemoryOverrideLib.inf | 25 ++= ++++=0D ArmVirtPkg/ArmVirt.dsc.inc | 1 += =0D ArmVirtPkg/ArmVirtQemu.dsc | 11 ++= -=0D ArmVirtPkg/ArmVirtQemuKernel.dsc | 1 += =0D ArmVirtPkg/Library/ArmPlatformLibQemu/AArch64/ArmPlatformHelper.S | 2 +-= =0D ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.c | 4 +-= =0D BaseTools/Scripts/GccBase.lds | 13 ++= -=0D MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 33 ++= ++++--=0D MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c | 69 ++= ++++++++++++++=0D MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 6 +-= =0D MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 24 ++= +---=0D MdePkg/Include/Library/PeCoffLib.h | 25 ++= ++++=0D MdePkg/Library/BasePeCoffLib/BasePeCoff.c | 83 ++= +++++++++++++++++-=0D 18 files changed, 392 insertions(+), 112 deletions(-)=0D create mode 100644 ArmPkg/Library/ArmSetMemoryOverrideLib/ArmSetMemoryOver= rideLib.c=0D create mode 100644 ArmPkg/Library/ArmSetMemoryOverrideLib/ArmSetMemoryOver= rideLib.inf=0D =0D -- =0D 2.39.1=0D =0D