From: "Yao, Jiewen" <jiewen.yao@intel.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"afish@apple.com" <afish@apple.com>,
"leif.lindholm@linaro.org" <leif.lindholm@linaro.org>,
"Kinney, Michael D" <michael.d.kinney@intel.com>,
"Gao, Liming" <liming.gao@intel.com>
Cc: "Tian, Feng" <feng.tian@intel.com>,
"lersek@redhat.com" <lersek@redhat.com>,
"Zeng, Star" <star.zeng@intel.com>,
"Yao, Jiewen" <jiewen.yao@intel.com>
Subject: Re: [PATCH v2 0/5] RFC: increased memory protection
Date: Sat, 25 Feb 2017 04:04:25 +0000 [thread overview]
Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503A8F539C@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <1487948699-3179-1-git-send-email-ard.biesheuvel@linaro.org>
Thank you Ard. I like this patch - simple and obvious.
I put all my comment together for your consideration.
1) Patch V2 1/5 -- reviewed-by: Jiewen.yao@Intel.com
2) Patch V2 2/5 - reviewed-by: Jiewen.yao@intel.com
3) Patch V2 3/5 - reviewed-by: Jiewen.yao@intel.com
4) Patch V2 4/5 -
4.1) Can we follow the style of other memory type definition? (Such as PcdMemoryProfileMemoryType)
The reason is that people may want to have fine granularity control for loader data or persistent memory.
My proposal is below:
//////////////////////////
## 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.<BR><BR>
#
# Below is bit mask for this PCD: (Order is same as UEFI spec)<BR>
# EfiReservedMemoryType 0x0001<BR>
# EfiLoaderCode 0x0002<BR>
# EfiLoaderData 0x0004<BR>
# EfiBootServicesCode 0x0008<BR>
# EfiBootServicesData 0x0010<BR>
# EfiRuntimeServicesCode 0x0020<BR>
# EfiRuntimeServicesData 0x0040<BR>
# EfiConventionalMemory 0x0080<BR>
# EfiUnusableMemory 0x0100<BR>
# EfiACPIReclaimMemory 0x0200<BR>
# EfiACPIMemoryNVS 0x0400<BR>
# EfiMemoryMappedIO 0x0800<BR>
# EfiMemoryMappedIOPortSpace 0x1000<BR>
# EfiPalCode 0x2000<BR>
# EfiPersistentMemory 0x4000<BR>
# OEM Reserved 0x4000000000000000<BR>
# OS Reserved 0x8000000000000000<BR>
#
# NOTE: User must NOT set NX protection for EfiLoaderCode / EfiBootServicesCode / EfiRuntimeServicesCode. <BR>
#
# e.g. 0x7FD5 can be used for all memory except Code. <BR>
# e.g. 0x7BD4 can be used for all memory except Code and ACPINVS/Reserved. <BR>
#
# @Prompt Set DXE memory protection policy.
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeMemoryProtectionPolicy|0x0000000|UINT64|0x00001048
//////////////////////////
Then the C-code can be like below:
//////////////////////////
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 (PcdMemoryProfileMemoryType) & TestBit) != 0) {
return EFI_MEMORY_XP;
} else {
return 0;
}
}
//////////////////////////
4.2) I prefer to setting default value to be 0x0 - to keep the compatibility, at least for X86 platform. (I have no strong opinion for ARM.)
4.3) I feel we might use a better name - PcdDxeNxMemoryProtectionPolicy (add "NX" keyword), so that people can know this PCD is to control NX attribute.
Maybe we can apply other protection such as RO or RP later.
What about your idea?
5) Patch V2 5/5 -
5.1) I think we should check the allocation happens IsInSmm, and skip ApplyMemoryProtection() if it is in Smm.
The reason is that SMM maintains its own page table.
Below code is for your reference.
//////////////////////////
BOOLEAN
IsInSmm (
VOID
)
{
BOOLEAN InSmm;
InSmm = FALSE;
if (gSmmBase2 != NULL) {
gSmmBase2->InSmm (gSmmBase2, &InSmm);
}
return InSmm;
}
//////////////////////////
5.2) I think we are not able to call ApplyMemoryProtection() inside of CoreAllocatePoolPages() and CoreFreePoolPages().
The reason is that: X86 CPU page table update algo might call AllocatePages(), to support page table split from big page to small page.
CoreAcquireMemoryLock() may fail in such case, because the memory map is locked in AllocatePool().
I think a safety way is to call ApplyMemoryProtection() at CoreAllocatePool(), after InstallMemoryAttributesTableOnMemoryAllocation(). We do same thing as CoreAllocatePage().
We can update CoreInternalAllocatePool() to return the necessary parameters back to indicate if CoreAllocatePoolPages() happens, and where is the new pages.
Same thing for CoreFreePool().
5.3) In order to reduce the fragmentation of X86 page table, I recommend we do a little enhancement in ApplyDxeMemoryProtectionPolicy().
Can we can combine the memory need NX together and call SetUefiImageMemoryAttributes() once?
You may refer to MergeMemoryMapForNotPresentEntry() in UefiCpuPkg\PiSmmCpuDxeSmm\SmmCpuMemoryManagement.c,
which combines the memory map entry together, if the adjacent entry requires same not-present attribute.
In this case, we could define MergeMemoryMapForNonExecutable() in MemoryProtection.c, and used by ApplyDxeMemoryProtectionPolicy().
I believe it helps X86 platforms.
Thank you
Yao Jiewen
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Ard
> Biesheuvel
> Sent: Friday, February 24, 2017 11:05 PM
> To: edk2-devel@lists.01.org; afish@apple.com; leif.lindholm@linaro.org; Kinney,
> Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>;
> Yao, Jiewen <jiewen.yao@intel.com>
> Cc: Tian, Feng <feng.tian@intel.com>; lersek@redhat.com; Zeng, Star
> <star.zeng@intel.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Subject: [edk2] [PATCH v2 0/5] RFC: increased memory protection
>
> Hello all,
>
> This is a proof of concept implementation that removes all executable
> permissions from writable memory regions, which greatly enhances security.
> It is based on Jiewen's recent work, which is a step in the right direction,
> but still leaves most of memory exploitable due to the default R+W+X
> permissions.
>
> The idea is that the implementation of the CPU arch protocol goes over the
> memory map and removes exec permissions from all regions that are not already
> marked as 'code. This requires some preparatory work to ensure that the
> DxeCore
> itself is covered by a BootServicesCode region, not a BootServicesData region.
> Exec permissions are re-granted selectively, when the PE/COFF loader allocates
> the space for it. Combined with Jiewen's code/data split, this removes all
> RWX mapped regions.
>
> Changes since v1:
> - allocate code pages for PE/COFF images in PeiCore, so that DxeCore pages have
> the expected memory type (as suggested by Jiewen)
> - add patch to inhibit page table updates while syncing the GCD memory space
> map with the page tables
> - add PCD to set memory protection policy, which allows the policy for reserved
> and ACPI/NVS memory to be configured separately
> - move attribute manipulation into DxeCore page allocation code: this way, we
> should be able to solve the EBC case by allocating BootServicesCode pool
> memory explicitly.
>
> Ard Biesheuvel (5):
> ArmPkg/CpuDxe: ignore attribute changes during SyncCacheConfig()
> MdeModulePkg/PeiCore: allocate BootServicesCode memory for PE/COFF
> images
> MdeModulePkg/DxeCore: pass pool type to CoreFreePoolPages ()
> MdeModulePkg: define PCD for DXE memory protection policy
> MdeModulePkg/DxeCore: implement memory protection policy
>
> ArmPkg/Drivers/CpuDxe/CpuDxe.c | 3 +
> ArmPkg/Drivers/CpuDxe/CpuDxe.h | 1 +
> ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c | 4 +
> MdeModulePkg/Core/Dxe/DxeMain.inf | 1 +
> MdeModulePkg/Core/Dxe/Mem/Imem.h | 2 +
> MdeModulePkg/Core/Dxe/Mem/Page.c | 106
> ++++++++++++++++++++
> MdeModulePkg/Core/Dxe/Mem/Pool.c | 5 +-
> MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 104
> ++++++++++++++++++-
> MdeModulePkg/Core/Pei/Image/Image.c | 10 +-
> MdeModulePkg/MdeModulePkg.dec | 16 +++
> 10 files changed, 246 insertions(+), 6 deletions(-)
>
> --
> 2.7.4
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
next prev parent reply other threads:[~2017-02-25 4:04 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-24 15:04 [PATCH v2 0/5] RFC: increased memory protection Ard Biesheuvel
2017-02-24 15:04 ` [PATCH v2 1/5] ArmPkg/CpuDxe: ignore attribute changes during SyncCacheConfig() Ard Biesheuvel
2017-02-24 15:04 ` [PATCH v2 2/5] MdeModulePkg/PeiCore: allocate BootServicesCode memory for PE/COFF images Ard Biesheuvel
2017-02-24 15:04 ` [PATCH v2 3/5] MdeModulePkg/DxeCore: pass pool type to CoreFreePoolPages () Ard Biesheuvel
2017-02-24 15:04 ` [PATCH v2 4/5] MdeModulePkg: define PCD for DXE memory protection policy Ard Biesheuvel
2017-02-24 15:04 ` [PATCH v2 5/5] MdeModulePkg/DxeCore: implement " Ard Biesheuvel
2017-02-25 4:04 ` Yao, Jiewen [this message]
2017-02-26 15:09 ` [PATCH v2 0/5] RFC: increased memory protection Ard Biesheuvel
2017-02-27 8:56 ` Laszlo Ersek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=74D8A39837DF1E4DA445A8C0B3885C503A8F539C@shsmsx102.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox