summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal
diff options
context:
space:
mode:
authorMichael Kubacki <michael.kubacki@microsoft.com>2020-04-11 04:49:43 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-04-21 02:20:51 +0000
commit1a258c7703e587f85885099dd57236cb45af82f8 (patch)
tree6f96af294d02465414626ea2958e4bcf78a739b8 /MdeModulePkg/Universal
parent7a7bedce25d257c1058d9a5212a3a0554c5d70a6 (diff)
downloadedk2-1a258c7703e587f85885099dd57236cb45af82f8.tar.gz
edk2-1a258c7703e587f85885099dd57236cb45af82f8.tar.bz2
edk2-1a258c7703e587f85885099dd57236cb45af82f8.zip
MdeModulePkg/ReportStatusCodeRouter: Revert end pointer on out of resources
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2665 ReportDispatcher() is called by a software module to report a status code. The interface is generic and can be called frequently throughout the boot under various conditions. A certain set of conditions can cause the currently implemented algorithm for resource exhaustion to fail. A sample scenario: 1. ReportStatusCode() is called at a TPL higher than one of the registered status code listeners making the call to the listener deferred until TPL is lowered. 2. Additional calls to ReportStatusCode() occur, so the data buffer continues to expand. 3. A call to ReportStatusCode() is made from within a memory allocation call (e.g. CoreAllocatePoolPages ()) which is protected from re- entrancy with mPoolMemoryLock. This will cause the ReallocatePool() call in ReportDispatcher() to fail. Because the end pointer was already moved to account for the data size, the end pointer is now moved beyond the buffer and invalid. This commit saves the original end pointer value into a local variable called "FailSafeEndPointer" which tracks a safe end pointer to revert to in the case the allocated buffer size (CallbackEntry->EndPointer - CallbackEntry->StatusCodeDataBuffer) is still not large enough for the data. Cc: Hao A Wu <hao.a.wu@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Kun Qin <Kun.Qin@microsoft.com> Cc: Liming Gao <liming.gao@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Dandan Bi <dandan.bi@intel.com>
Diffstat (limited to 'MdeModulePkg/Universal')
-rw-r--r--MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c
index 5df83027c6..27939235dc 100644
--- a/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c
+++ b/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c
@@ -238,6 +238,7 @@ ReportDispatcher (
RSC_DATA_ENTRY *RscData;
EFI_STATUS Status;
VOID *NewBuffer;
+ EFI_PHYSICAL_ADDRESS FailSafeEndPointer;
//
// Use atom operation to avoid the reentant of report.
@@ -268,6 +269,7 @@ ReportDispatcher (
// If callback is registered with TPL lower than TPL_HIGH_LEVEL, event must be signaled at boot time to possibly wait for
// allowed TPL to report status code. Related data should also be stored in data buffer.
//
+ FailSafeEndPointer = CallbackEntry->EndPointer;
CallbackEntry->EndPointer = ALIGN_VARIABLE (CallbackEntry->EndPointer);
RscData = (RSC_DATA_ENTRY *) (UINTN) CallbackEntry->EndPointer;
CallbackEntry->EndPointer += sizeof (RSC_DATA_ENTRY);
@@ -286,6 +288,7 @@ ReportDispatcher (
(VOID *) (UINTN) CallbackEntry->StatusCodeDataBuffer
);
if (NewBuffer != NULL) {
+ FailSafeEndPointer = (EFI_PHYSICAL_ADDRESS) (UINTN) NewBuffer + (FailSafeEndPointer - CallbackEntry->StatusCodeDataBuffer);
CallbackEntry->EndPointer = (EFI_PHYSICAL_ADDRESS) (UINTN) NewBuffer + (CallbackEntry->EndPointer - CallbackEntry->StatusCodeDataBuffer);
CallbackEntry->StatusCodeDataBuffer = (EFI_PHYSICAL_ADDRESS) (UINTN) NewBuffer;
CallbackEntry->BufferSize *= 2;
@@ -297,6 +300,7 @@ ReportDispatcher (
// If data buffer is used up, do not report for this time.
//
if (CallbackEntry->EndPointer > (CallbackEntry->StatusCodeDataBuffer + CallbackEntry->BufferSize)) {
+ CallbackEntry->EndPointer = FailSafeEndPointer;
continue;
}