Introduce a new IsLinearAddressRangeValid() function to validate a given
address range and check whether or not it is valid.
This function is useful for validating ranges of memory addresses during
stack traces in X64.
Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Eric Dong <eric.dong@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Requested-by: Brian Johnson <brian.johnson@hpe.com>
Signed-off-by: Paulo Alcantara <paulo@paulo.ac>
---
UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c | 40 ++++++++++++++++++++
UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h | 18 +++++++++
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c | 40 ++++++++++++--------
3 files changed, 83 insertions(+), 15 deletions(-)
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
index 7ac13640de..e1dd054259 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
@@ -589,3 +589,43 @@ IsLinearAddressValid (
return AddressValid;
}
+
+/**
+ Check if a linear address range is valid.
+
+ @param[in] Cr0 CR0 control register.
+ @param[in] Cr3 CR3 control register.
+ @param[in] Cr4 CR4 control register.
+ @param[in] LinearAddressStart Linear address start.
+ @param[in] LinearAddressEnd Linear address end.
+**/
+BOOLEAN
+IsLinearAddressRangeValid (
+ IN UINTN Cr0,
+ IN UINTN Cr3,
+ IN UINTN Cr4,
+ IN UINTN LinearAddressStart,
+ IN UINTN LinearAddressEnd
+ )
+{
+ //
+ // Check for valid input parameters
+ //
+ if (LinearAddressStart == 0 || LinearAddressEnd == 0 ||
+ LinearAddressStart > LinearAddressEnd) {
+ return FALSE;
+ }
+
+ //
+ // Validate all linear addresses within the given range
+ //
+ for (LinearAddressStart &= ~(SIZE_4KB - 1);
+ LinearAddressStart <= LinearAddressEnd;
+ LinearAddressStart += SIZE_4KB) {
+ if (!IsLinearAddressValid (Cr0, Cr3, Cr4, LinearAddressStart)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
index 1b51034c25..075f668290 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
@@ -346,5 +346,23 @@ IsLinearAddressValid (
IN UINTN LinearAddress
);
+/**
+ Check if a linear address range is valid.
+
+ @param[in] Cr0 CR0 control register.
+ @param[in] Cr3 CR3 control register.
+ @param[in] Cr4 CR4 control register.
+ @param[in] LinearAddressStart Linear address start.
+ @param[in] LinearAddressEnd Linear address end.
+**/
+BOOLEAN
+IsLinearAddressRangeValid (
+ IN UINTN Cr0,
+ IN UINTN Cr3,
+ IN UINTN Cr4,
+ IN UINTN LinearAddressStart,
+ IN UINTN LinearAddressEnd
+ );
+
#endif
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
index 71d2d2f5d4..4d8c9b0a89 100644
--- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
+++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
@@ -415,6 +415,8 @@ DumpStackContents (
UINTN Cr0;
UINTN Cr3;
UINTN Cr4;
+ UINTN RspAddressStart;
+ UINTN RspAddressEnd;
//
// Get current stack pointer
@@ -436,21 +438,29 @@ DumpStackContents (
Cr3 = SystemContext.SystemContextX64->Cr3;
Cr4 = SystemContext.SystemContextX64->Cr4;
+ //
+ // Calculate address range of the stack pointers
+ //
+ RspAddressStart = (UINTN)CurrentRsp;
+ RspAddressEnd =
+ RspAddressStart + (UINTN)UnwoundStacksCount * CPU_STACK_ALIGNMENT;
+
+ //
+ // Validate address range of stack pointers
+ //
+ if (!IsLinearAddressRangeValid (Cr0, Cr3, Cr4, RspAddressStart,
+ RspAddressEnd)) {
+ InternalPrintMessage ("%a: attempted to dereference an invalid stack "
+ "pointer at 0x%016lx - 0x%016lx\n", __FUNCTION__,
+ RspAddressStart, RspAddressEnd);
+ return;
+ }
+
//
// Dump out stack contents
//
InternalPrintMessage ("\nStack dump:\n");
while (UnwoundStacksCount-- > 0) {
- //
- // Check for a valid stack pointer address
- //
- if (!IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)CurrentRsp) ||
- !IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)CurrentRsp + 8)) {
- InternalPrintMessage ("%a: attempted to dereference an invalid stack "
- "pointer at 0x%016lx\n", __FUNCTION__, CurrentRsp);
- break;
- }
-
InternalPrintMessage (
"0x%016lx: %016lx %016lx\n",
CurrentRsp,
@@ -459,7 +469,7 @@ DumpStackContents (
);
//
- // Point to next stack
+ // Point to next stack pointer
//
CurrentRsp += CPU_STACK_ALIGNMENT;
}
@@ -571,8 +581,8 @@ DumpImageModuleNames (
//
// Check for a valid frame pointer
//
- if (!IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)Rbp + 8) ||
- !IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)Rbp)) {
+ if (!IsLinearAddressRangeValid (Cr0, Cr3, Cr4, (UINTN)Rbp,
+ (UINTN)Rbp + 8)) {
InternalPrintMessage ("%a: attempted to dereference an invalid frame "
"pointer at 0x%016lx\n", __FUNCTION__, Rbp);
break;
@@ -722,8 +732,8 @@ DumpStacktrace (
//
// Check for valid frame pointer
//
- if (!IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)Rbp + 8) ||
- !IsLinearAddressValid (Cr0, Cr3, Cr4, (UINTN)Rbp)) {
+ if (!IsLinearAddressRangeValid (Cr0, Cr3, Cr4, (UINTN)Rbp,
+ (UINTN)Rbp + 8)) {
InternalPrintMessage ("%a: attempted to dereference an invalid frame "
"pointer at 0x%016lx\n", __FUNCTION__, Rbp);
break;
--
2.14.3
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel