MdeModulePkg/Core: fix feature conflict between NX and heap guard

Considering following scenario (both NX memory protection and heap guard
are enabled):

   1. Allocate 3 pages. The attributes of adjacent memory pages will be

      |NOT-PRESENT|  present  |  present  |  present  |NOT-PRESENT|

   2. Free the middle page. The attributes of adjacent memory pages should be

      |NOT-PRESENT|  present  |NOT-PRESENT|  present  |NOT-PRESENT|

      But the NX feature will overwrite the attributes of middle page. So it
      looks still like below, which is wrong.

      |NOT-PRESENT|  present  |  PRESENT  |  present  |NOT-PRESENT|

The solution is checking the first and/or last page of a memory block to be
marked as NX, and skipping them if they are Guard pages.

Cc: Star Zeng <star.zeng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
This commit is contained in:
Jian J Wang 2018-01-29 20:03:33 +08:00 committed by Star Zeng
parent 9b17c6511d
commit a6a0a59756
3 changed files with 46 additions and 0 deletions

View File

@ -728,6 +728,20 @@ IsPageTypeToGuard (
return IsMemoryTypeToGuard (MemoryType, AllocateType, GUARD_HEAP_TYPE_PAGE); return IsMemoryTypeToGuard (MemoryType, AllocateType, GUARD_HEAP_TYPE_PAGE);
} }
/**
Check to see if the heap guard is enabled for page and/or pool allocation.
@return TRUE/FALSE.
**/
BOOLEAN
IsHeapGuardEnabled (
VOID
)
{
return IsMemoryTypeToGuard (EfiMaxMemoryType, AllocateAnyPages,
GUARD_HEAP_TYPE_POOL|GUARD_HEAP_TYPE_PAGE);
}
/** /**
Set head Guard and tail Guard for the given memory range. Set head Guard and tail Guard for the given memory range.

View File

@ -389,6 +389,16 @@ AdjustPoolHeadF (
IN EFI_PHYSICAL_ADDRESS Memory IN EFI_PHYSICAL_ADDRESS Memory
); );
/**
Check to see if the heap guard is enabled for page and/or pool allocation.
@return TRUE/FALSE.
**/
BOOLEAN
IsHeapGuardEnabled (
VOID
);
extern BOOLEAN mOnGuarding; extern BOOLEAN mOnGuarding;
#endif #endif

View File

@ -48,6 +48,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SimpleFileSystem.h> #include <Protocol/SimpleFileSystem.h>
#include "DxeMain.h" #include "DxeMain.h"
#include "Mem/HeapGuard.h"
#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP) #define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP)
#define MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO) #define MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO)
@ -1202,6 +1203,27 @@ ApplyMemoryProtectionPolicy (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
//
// Don't overwrite Guard pages, which should be the first and/or last page,
// if any.
//
if (IsHeapGuardEnabled ()) {
if (IsGuardPage (Memory)) {
Memory += EFI_PAGE_SIZE;
Length -= EFI_PAGE_SIZE;
if (Length == 0) {
return EFI_SUCCESS;
}
}
if (IsGuardPage (Memory + Length - EFI_PAGE_SIZE)) {
Length -= EFI_PAGE_SIZE;
if (Length == 0) {
return EFI_SUCCESS;
}
}
}
// //
// Update the executable permissions according to the DXE memory // Update the executable permissions according to the DXE memory
// protection policy, but only if // protection policy, but only if