]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/Core/Dxe: Acquire a lock when iterating gHandleList
authorHua Ma <hua.ma@intel.com>
Mon, 11 Oct 2021 03:43:12 +0000 (11:43 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 14 Oct 2021 03:27:20 +0000 (03:27 +0000)
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>
MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
MdeModulePkg/Core/Dxe/Hand/Handle.c
MdeModulePkg/Core/Dxe/Hand/Handle.h
MdeModulePkg/Core/Dxe/Hand/Notify.c

index feabf12faf17a37409622e2eafbdf086dea261da..12a202417c2d5e660394b8ae03c7d79dd7074b26 100644 (file)
@@ -68,7 +68,12 @@ CoreConnectController (
   //\r
   // Make sure ControllerHandle is valid\r
   //\r
+  CoreAcquireProtocolLock ();\r
+\r
   Status = CoreValidateHandle (ControllerHandle);\r
+\r
+  CoreReleaseProtocolLock ();\r
+\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -268,7 +273,12 @@ AddSortedDriverBindingProtocol (
   //\r
   // Make sure the DriverBindingHandle is valid\r
   //\r
+  CoreAcquireProtocolLock ();\r
+\r
   Status = CoreValidateHandle (DriverBindingHandle);\r
+\r
+  CoreReleaseProtocolLock ();\r
+\r
   if (EFI_ERROR (Status)) {\r
     return;\r
   }\r
@@ -746,8 +756,11 @@ CoreDisconnectController (
   //\r
   // Make sure ControllerHandle is valid\r
   //\r
+  CoreAcquireProtocolLock ();\r
+\r
   Status = CoreValidateHandle (ControllerHandle);\r
   if (EFI_ERROR (Status)) {\r
+    CoreReleaseProtocolLock ();\r
     return Status;\r
   }\r
 \r
@@ -757,10 +770,13 @@ CoreDisconnectController (
   if (ChildHandle != NULL) {\r
     Status = CoreValidateHandle (ChildHandle);\r
     if (EFI_ERROR (Status)) {\r
+      CoreReleaseProtocolLock ();\r
       return Status;\r
     }\r
   }\r
 \r
+  CoreReleaseProtocolLock ();\r
+\r
   Handle = ControllerHandle;\r
 \r
   //\r
index 6eccb41ecb5cfcb09a03fcb2e06b26271e43b64d..92979281b74a2a76e0f77c067660d3542329d712 100644 (file)
@@ -53,6 +53,7 @@ CoreReleaseProtocolLock (
 \r
 /**\r
   Check whether a handle is a valid EFI_HANDLE\r
+  The gProtocolDatabaseLock must be owned\r
 \r
   @param  UserHandle             The handle to check\r
 \r
@@ -72,6 +73,8 @@ CoreValidateHandle (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  ASSERT_LOCKED(&gProtocolDatabaseLock);\r
+\r
   for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {\r
     Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);\r
     if (Handle == (IHANDLE *) UserHandle) {\r
@@ -720,19 +723,19 @@ CoreUninstallProtocolInterface (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // Lock the protocol database\r
+  //\r
+  CoreAcquireProtocolLock ();\r
+\r
   //\r
   // Check that UserHandle is a valid handle\r
   //\r
   Status = CoreValidateHandle (UserHandle);\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    goto Done;\r
   }\r
 \r
-  //\r
-  // Lock the protocol database\r
-  //\r
-  CoreAcquireProtocolLock ();\r
-\r
   //\r
   // Check that Protocol exists on UserHandle, and Interface matches the interface in the database\r
   //\r
@@ -1010,12 +1013,17 @@ CoreOpenProtocol (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // Lock the protocol database\r
+  //\r
+  CoreAcquireProtocolLock ();\r
+\r
   //\r
   // Check for invalid UserHandle\r
   //\r
   Status = CoreValidateHandle (UserHandle);\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    goto Done;\r
   }\r
 \r
   //\r
@@ -1025,31 +1033,32 @@ CoreOpenProtocol (
   case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :\r
     Status = CoreValidateHandle (ImageHandle);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
     Status = CoreValidateHandle (ControllerHandle);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
     if (UserHandle == ControllerHandle) {\r
-      return EFI_INVALID_PARAMETER;\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
     }\r
     break;\r
   case EFI_OPEN_PROTOCOL_BY_DRIVER :\r
   case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :\r
     Status = CoreValidateHandle (ImageHandle);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
     Status = CoreValidateHandle (ControllerHandle);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
     break;\r
   case EFI_OPEN_PROTOCOL_EXCLUSIVE :\r
     Status = CoreValidateHandle (ImageHandle);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
     break;\r
   case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :\r
@@ -1057,13 +1066,10 @@ CoreOpenProtocol (
   case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :\r
     break;\r
   default:\r
-    return EFI_INVALID_PARAMETER;\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
   }\r
 \r
-  //\r
-  // Lock the protocol database\r
-  //\r
-  CoreAcquireProtocolLock ();\r
 \r
   //\r
   // Look at each protocol interface for a match\r
@@ -1246,32 +1252,33 @@ CoreCloseProtocol (
   LIST_ENTRY          *Link;\r
   OPEN_PROTOCOL_DATA  *OpenData;\r
 \r
+  //\r
+  // Lock the protocol database\r
+  //\r
+  CoreAcquireProtocolLock ();\r
+\r
   //\r
   // Check for invalid parameters\r
   //\r
   Status = CoreValidateHandle (UserHandle);\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    goto Done;\r
   }\r
   Status = CoreValidateHandle (AgentHandle);\r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    goto Done;\r
   }\r
   if (ControllerHandle != NULL) {\r
     Status = CoreValidateHandle (ControllerHandle);\r
     if (EFI_ERROR (Status)) {\r
-      return Status;\r
+      goto Done;\r
     }\r
   }\r
   if (Protocol == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
   }\r
 \r
-  //\r
-  // Lock the protocol database\r
-  //\r
-  CoreAcquireProtocolLock ();\r
-\r
   //\r
   // Look at each protocol interface for a match\r
   //\r
@@ -1443,13 +1450,6 @@ CoreProtocolsPerHandle (
   UINTN                               ProtocolCount;\r
   EFI_GUID                            **Buffer;\r
 \r
-  Status = CoreValidateHandle (UserHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Handle = (IHANDLE *)UserHandle;\r
-\r
   if (ProtocolBuffer == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1464,6 +1464,13 @@ CoreProtocolsPerHandle (
 \r
   CoreAcquireProtocolLock ();\r
 \r
+  Status = CoreValidateHandle (UserHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Handle = (IHANDLE *)UserHandle;\r
+\r
   for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
     ProtocolCount++;\r
   }\r
index 83eb2b9f3afee2cac069cacbaeebdbe9314e6666..3f83e3af15a3f19b69fa4907c470b511092e63aa 100644 (file)
@@ -242,6 +242,7 @@ CoreReleaseProtocolLock (
 \r
 /**\r
   Check whether a handle is a valid EFI_HANDLE\r
+  The gProtocolDatabaseLock must be owned\r
 \r
   @param  UserHandle             The handle to check\r
 \r
index 553413a3509cf231363baa889aeac90043510abb..d05f95207f7373cfca839b4b65eb39ebc15b1795 100644 (file)
@@ -188,22 +188,21 @@ CoreReinstallProtocolInterface (
   PROTOCOL_INTERFACE        *Prot;\r
   PROTOCOL_ENTRY            *ProtEntry;\r
 \r
-  Status = CoreValidateHandle (UserHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
   if (Protocol == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Handle = (IHANDLE *) UserHandle;\r
-\r
   //\r
   // Lock the protocol database\r
   //\r
   CoreAcquireProtocolLock ();\r
 \r
+  Status = CoreValidateHandle (UserHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Handle = (IHANDLE *) UserHandle;\r
   //\r
   // Check that Protocol exists on UserHandle, and Interface matches the interface in the database\r
   //\r