MdeModulePkg/UefiBootManagerLib: Avoid buggy USB short-form expanding
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 19 Apr 2017 09:16:27 +0000 (17:16 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Thu, 20 Apr 2017 08:31:05 +0000 (16:31 +0800)
When a load option points to a physical UsbIo controller, whose
device path contains UsbClass or UsbWwid node, old logic
unconditionally treats it as a short-form device path and expands
it. But the expanding gets the exactly same device path, and the
device path is passed to BmGetNextLoadOptionDevicePath() which
then passes this device path to BmExpandUsbDevicePath() again.
This causes a infinite recursion.

The patch avoids the USB short-form expanding when the device path
points to a physical UsbIo controller.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Michael Turner <Michael.Turner@microsoft.com>
MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c

index aa79c9075f8adc6969f4d79d565cbdd8a076bab8..d6844823aa5519c72a182d033000ebd07fe744d4 100644 (file)
@@ -1546,26 +1546,35 @@ BmGetNextLoadOptionDevicePath (
     //\r
     return BmExpandUriDevicePath (FilePath, FullPath);\r
   } else {\r
-    for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
-      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&\r
-          ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) || (DevicePathSubType (Node) == MSG_USB_WWID_DP))) {\r
-        break;\r
+    Node = FilePath;\r
+    Status = gBS->LocateDevicePath (&gEfiUsbIoProtocolGuid, &Node, &Handle);\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Only expand the USB WWID/Class device path\r
+      // when FilePath doesn't point to a physical UsbIo controller.\r
+      // Otherwise, infinite recursion will happen.\r
+      //\r
+      for (Node = FilePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {\r
+        if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) &&\r
+            ((DevicePathSubType (Node) == MSG_USB_CLASS_DP) || (DevicePathSubType (Node) == MSG_USB_WWID_DP))) {\r
+          break;\r
+        }\r
       }\r
-    }\r
 \r
-    //\r
-    // Expand the USB WWID/Class device path\r
-    //\r
-    if (!IsDevicePathEnd (Node)) {\r
-      if (FilePath == Node) {\r
-        //\r
-        // Boot Option device path starts with USB Class or USB WWID device path.\r
-        // For Boot Option device path which doesn't begin with the USB Class or\r
-        // USB WWID device path, it's not needed to connect again here.\r
-        //\r
-        BmConnectUsbShortFormDevicePath (FilePath);\r
+      //\r
+      // Expand the USB WWID/Class device path\r
+      //\r
+      if (!IsDevicePathEnd (Node)) {\r
+        if (FilePath == Node) {\r
+          //\r
+          // Boot Option device path starts with USB Class or USB WWID device path.\r
+          // For Boot Option device path which doesn't begin with the USB Class or\r
+          // USB WWID device path, it's not needed to connect again here.\r
+          //\r
+          BmConnectUsbShortFormDevicePath (FilePath);\r
+        }\r
+        return BmExpandUsbDevicePath (FilePath, FullPath, Node);\r
       }\r
-      return BmExpandUsbDevicePath (FilePath, FullPath, Node);\r
     }\r
   }\r
 \r