Skip to content

Commit

Permalink
QuarkSocPkg/QncSmmDispatcher: Fix use after free issue
Browse files Browse the repository at this point in the history
Update Quark North Cluster SMM dispatcher logic to handle
case where an SMI handler unregisters itself.

https://bugzilla.tianocore.org/show_bug.cgi?id=51

This issue was reproduced using the unit test at:

https://github.com/mdkinney/edk2/tree/Bug51/Reproduce

An ASSERT() is generated the 4th time the periodic SMI
handler is triggered when the periodic SMI handler
unregisters itself.  After applying this patch, the
DEBUG() message from the periodic SMI handler in this
unit test is generated 4 times, the periodic SMI handler
is unregistered, and the UEFI Shell works as expected.

Cc: Kelly Steele <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <[email protected]>
Reviewed-by: Kelly Steele <[email protected]>
  • Loading branch information
mdkinney committed Oct 7, 2016
1 parent 29f169d commit 5f82e02
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ struct _DATABASE_RECORD {
UINT32 Signature;
LIST_ENTRY Link;

BOOLEAN Processed;

//
// Status and Enable bit description
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ QNCSmmCoreDispatcher (
BOOLEAN ChildWasDispatched;

DATABASE_RECORD *RecordInDb;
DATABASE_RECORD ActiveRecordInDb;
LIST_ENTRY *LinkInDb;
DATABASE_RECORD *RecordToExhaust;
LIST_ENTRY *LinkToExhaust;
Expand All @@ -613,6 +614,16 @@ QNCSmmCoreDispatcher (
Status = EFI_WARN_INTERRUPT_SOURCE_PENDING;
ChildWasDispatched = FALSE;

//
// Mark all child handlers as not processed
//
LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
RecordInDb->Processed = FALSE;
LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, LinkInDb);
}

//
// Preserve Index registers
//
Expand All @@ -634,6 +645,12 @@ QNCSmmCoreDispatcher (

while ((!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) && (ResetListSearch == FALSE)) {
RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
//
// Make a copy of the record that contains an active SMI source,
// because un-register maybe invoked in callback function and
// RecordInDb maybe released
//
CopyMem (&ActiveRecordInDb, RecordInDb, sizeof (ActiveRecordInDb));

//
// look for the first active source
Expand Down Expand Up @@ -663,6 +680,13 @@ QNCSmmCoreDispatcher (
//
while (!IsNull (&mPrivateData.CallbackDataBase, LinkToExhaust)) {
RecordToExhaust = DATABASE_RECORD_FROM_LINK (LinkToExhaust);
LinkToExhaust = GetNextNode (&mPrivateData.CallbackDataBase, LinkToExhaust);
if (RecordToExhaust->Processed) {
//
// Record has already been processed. Continue with next child handler.
//
continue;
}

if (CompareSources (&RecordToExhaust->SrcDesc, &ActiveSource)) {
//
Expand Down Expand Up @@ -692,6 +716,11 @@ QNCSmmCoreDispatcher (
ContextsMatch = TRUE;
}

//
// Mark this child handler so it will not be processed again
//
RecordToExhaust->Processed = TRUE;

if (ContextsMatch) {

if (RecordToExhaust->BufferSize != 0) {
Expand Down Expand Up @@ -720,11 +749,13 @@ QNCSmmCoreDispatcher (
SxChildWasDispatched = TRUE;
}
}
//
// Can not use RecordInDb after this point because Callback may have unregistered RecordInDb
// Restart processing of SMI handlers from the begining of the linked list because the
// state of the linked listed may have been modified due to unregister actions in the Callback.
//
LinkToExhaust = GetFirstNode (&mPrivateData.CallbackDataBase);
}
//
// Get next record in DB
//
LinkToExhaust = GetNextNode (&mPrivateData.CallbackDataBase, &RecordToExhaust->Link);
}

if (RecordInDb->ClearSource == NULL) {
Expand All @@ -736,7 +767,7 @@ QNCSmmCoreDispatcher (
//
// This source requires special handling to clear
//
RecordInDb->ClearSource (&ActiveSource);
ActiveRecordInDb.ClearSource (&ActiveSource);
}

if (ChildWasDispatched) {
Expand Down

0 comments on commit 5f82e02

Please sign in to comment.