mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/Core/Dxe: Acquire a lock when iterating gHandleList
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3680 This patch fixes the following issue: The global variable gHandleList is a linked list. This list is locked when a entry is added or removed from the list, but there is no lock when iterating this list in function CoreValidateHandle(). It can lead to "Handle.c (76): CR has Bad Signature" assertion if the iterated entry in the list is just removed by other task during iterating. Currently some caller functions of CoreValidateHandle() have CoreAcquireProtocolLock(), but some caller functions of CoreValidateHandle() do not CoreAcquireProtocolLock(). Add CoreAcquireProtocolLock() always when CoreValidateHandle() is called, Also, A lock check is added in the CoreValidateHandle(). Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Dandan Bi <dandan.bi@intel.com> Cc: Ray Ni <ray.ni@intel.com> Signed-off-by: Hua Ma <hua.ma@intel.com> Reviewed-by: Dandan Bi <dandan.bi@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
This commit is contained in:
parent
43b3840873
commit
a7fcab7aa3
|
@ -68,7 +68,12 @@ CoreConnectController (
|
|||
//
|
||||
// Make sure ControllerHandle is valid
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
Status = CoreValidateHandle (ControllerHandle);
|
||||
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
@ -268,7 +273,12 @@ AddSortedDriverBindingProtocol (
|
|||
//
|
||||
// Make sure the DriverBindingHandle is valid
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
Status = CoreValidateHandle (DriverBindingHandle);
|
||||
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return;
|
||||
}
|
||||
|
@ -746,8 +756,11 @@ CoreDisconnectController (
|
|||
//
|
||||
// Make sure ControllerHandle is valid
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
Status = CoreValidateHandle (ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
CoreReleaseProtocolLock ();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -757,10 +770,13 @@ CoreDisconnectController (
|
|||
if (ChildHandle != NULL) {
|
||||
Status = CoreValidateHandle (ChildHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
CoreReleaseProtocolLock ();
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
CoreReleaseProtocolLock ();
|
||||
|
||||
Handle = ControllerHandle;
|
||||
|
||||
//
|
||||
|
|
|
@ -53,6 +53,7 @@ CoreReleaseProtocolLock (
|
|||
|
||||
/**
|
||||
Check whether a handle is a valid EFI_HANDLE
|
||||
The gProtocolDatabaseLock must be owned
|
||||
|
||||
@param UserHandle The handle to check
|
||||
|
||||
|
@ -72,6 +73,8 @@ CoreValidateHandle (
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ASSERT_LOCKED(&gProtocolDatabaseLock);
|
||||
|
||||
for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {
|
||||
Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
|
||||
if (Handle == (IHANDLE *) UserHandle) {
|
||||
|
@ -720,19 +723,19 @@ CoreUninstallProtocolInterface (
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Check that UserHandle is a valid handle
|
||||
//
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Check that Protocol exists on UserHandle, and Interface matches the interface in the database
|
||||
//
|
||||
|
@ -1010,12 +1013,17 @@ CoreOpenProtocol (
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Check for invalid UserHandle
|
||||
//
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1025,31 +1033,32 @@ CoreOpenProtocol (
|
|||
case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :
|
||||
Status = CoreValidateHandle (ImageHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
Status = CoreValidateHandle (ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
if (UserHandle == ControllerHandle) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
break;
|
||||
case EFI_OPEN_PROTOCOL_BY_DRIVER :
|
||||
case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :
|
||||
Status = CoreValidateHandle (ImageHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
Status = CoreValidateHandle (ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
break;
|
||||
case EFI_OPEN_PROTOCOL_EXCLUSIVE :
|
||||
Status = CoreValidateHandle (ImageHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
break;
|
||||
case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :
|
||||
|
@ -1057,13 +1066,10 @@ CoreOpenProtocol (
|
|||
case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :
|
||||
break;
|
||||
default:
|
||||
return EFI_INVALID_PARAMETER;
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Look at each protocol interface for a match
|
||||
|
@ -1246,32 +1252,33 @@ CoreCloseProtocol (
|
|||
LIST_ENTRY *Link;
|
||||
OPEN_PROTOCOL_DATA *OpenData;
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Check for invalid parameters
|
||||
//
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
Status = CoreValidateHandle (AgentHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
if (ControllerHandle != NULL) {
|
||||
Status = CoreValidateHandle (ControllerHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
if (Protocol == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
Status = EFI_INVALID_PARAMETER;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
//
|
||||
// Look at each protocol interface for a match
|
||||
//
|
||||
|
@ -1443,13 +1450,6 @@ CoreProtocolsPerHandle (
|
|||
UINTN ProtocolCount;
|
||||
EFI_GUID **Buffer;
|
||||
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Handle = (IHANDLE *)UserHandle;
|
||||
|
||||
if (ProtocolBuffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -1464,6 +1464,13 @@ CoreProtocolsPerHandle (
|
|||
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Handle = (IHANDLE *)UserHandle;
|
||||
|
||||
for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
|
||||
ProtocolCount++;
|
||||
}
|
||||
|
|
|
@ -242,6 +242,7 @@ CoreReleaseProtocolLock (
|
|||
|
||||
/**
|
||||
Check whether a handle is a valid EFI_HANDLE
|
||||
The gProtocolDatabaseLock must be owned
|
||||
|
||||
@param UserHandle The handle to check
|
||||
|
||||
|
|
|
@ -188,22 +188,21 @@ CoreReinstallProtocolInterface (
|
|||
PROTOCOL_INTERFACE *Prot;
|
||||
PROTOCOL_ENTRY *ProtEntry;
|
||||
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (Protocol == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Handle = (IHANDLE *) UserHandle;
|
||||
|
||||
//
|
||||
// Lock the protocol database
|
||||
//
|
||||
CoreAcquireProtocolLock ();
|
||||
|
||||
Status = CoreValidateHandle (UserHandle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Handle = (IHANDLE *) UserHandle;
|
||||
//
|
||||
// Check that Protocol exists on UserHandle, and Interface matches the interface in the database
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue