MdeModulePkg/DxeCore: Implement heap guard feature for UEFI
authorJian J Wang <jian.j.wang@intel.com>
Tue, 14 Nov 2017 02:55:26 +0000 (10:55 +0800)
committerStar Zeng <star.zeng@intel.com>
Fri, 17 Nov 2017 03:03:17 +0000 (11:03 +0800)
commit235a4490c8ce8b6dbac49e6ae3559cb73d6bf620
tree58340b2f60e284e9b4fda095a02bc1cd6facc0eb
parent99cc7b9507fa4d1efbf1b509b538905418712add
MdeModulePkg/DxeCore: Implement heap guard feature for UEFI

This feature makes use of paging mechanism to add a hidden (not present)
page just before and after the allocated memory block. If the code tries
to access memory outside of the allocated part, page fault exception will
be triggered.

This feature is controlled by three PCDs:

    gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPropertyMask
    gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPoolType
    gEfiMdeModulePkgTokenSpaceGuid.PcdHeapGuardPageType

BIT0 and BIT1 of PcdHeapGuardPropertyMask can be used to enable or disable
memory guard for page and pool respectively. PcdHeapGuardPoolType and/or
PcdHeapGuardPageType are used to enable or disable guard for specific type
of memory. For example, we can turn on guard only for EfiBootServicesData
and EfiRuntimeServicesData by setting the PCD with value 0x50.

Pool memory is not ususally integer multiple of one page, and is more likely
less than a page. There's no way to monitor the overflow at both top and
bottom of pool memory. BIT7 of PcdHeapGuardPropertyMask is used to control
how to position the head of pool memory so that it's easier to catch memory
overflow in memory growing direction or in decreasing direction.

Note1: Turning on heap guard, especially pool guard, will introduce too many
memory fragments. Windows 10 has a limitation in its boot loader, which
accepts at most 512 memory descriptors passed from BIOS. This will prevent
Windows 10 from booting if heap guard is enabled. The latest Linux
distribution with grub boot loader has no such issue. Normally it's not
recommended to enable this feature in production build of BIOS.

Note2: Don't enable this feature for NT32 emulation platform which doesn't
support paging.

Cc: Star Zeng <star.zeng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
MdeModulePkg/Core/Dxe/DxeMain.inf
MdeModulePkg/Core/Dxe/Mem/HeapGuard.c [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Mem/HeapGuard.h [new file with mode: 0644]
MdeModulePkg/Core/Dxe/Mem/Imem.h
MdeModulePkg/Core/Dxe/Mem/Page.c
MdeModulePkg/Core/Dxe/Mem/Pool.c
MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c