]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbDesc.c
index 9687eb0bca51c40f2683cb78672459c70c2e0258..a64f33fde67a5aa066faf3c5bea5d38215155600 100644 (file)
@@ -2,14 +2,8 @@
 \r
     Manage Usb Descriptor List\r
 \r
-Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -177,6 +171,18 @@ UsbCreateDesc (
     DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);\r
     CtrlLen = sizeof (USB_ENDPOINT_DESC);\r
     break;\r
+\r
+  default:\r
+    ASSERT (FALSE);\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Total length is too small that cannot hold the single descriptor header plus data.\r
+  //\r
+  if (Len <= sizeof (USB_DESC_HEAD)) {\r
+    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len));\r
+    return NULL;\r
   }\r
 \r
   //\r
@@ -184,24 +190,44 @@ UsbCreateDesc (
   // format. Skip the descriptor that isn't of this Type\r
   //\r
   Offset = 0;\r
-  Head   = (USB_DESC_HEAD*)DescBuf;\r
+  Head   = (USB_DESC_HEAD *)DescBuf;\r
+  while (Offset < Len - sizeof (USB_DESC_HEAD)) {\r
+    //\r
+    // Above condition make sure Head->Len and Head->Type are safe to access\r
+    //\r
+    Head = (USB_DESC_HEAD *)&DescBuf[Offset];\r
 \r
-  while ((Offset < Len) && (Head->Type != Type)) {\r
-    Offset += Head->Len;\r
-    if (Len <= Offset) {\r
-      DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Beyond boundary!\n"));\r
+    if (Head->Len == 0) {\r
+      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));\r
       return NULL;\r
     }\r
-    Head    = (USB_DESC_HEAD*)(DescBuf + Offset);\r
-    if (Head->Len == 0) {\r
-      DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));\r
+\r
+    //\r
+    // Make sure no overflow when adding Head->Len to Offset.\r
+    //\r
+    if (Head->Len > MAX_UINTN - Offset) {\r
+      DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head->Len));\r
       return NULL;\r
     }\r
+\r
+    Offset += Head->Len;\r
+\r
+    if (Head->Type == Type) {\r
+      break;\r
+    }\r
   }\r
 \r
-  if ((Len <= Offset)      || (Len < Offset + DescLen) ||\r
-      (Head->Type != Type) || (Head->Len != DescLen)) {\r
-    DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor\n"));\r
+  //\r
+  // Head->Len is invalid resulting data beyond boundary, or\r
+  // Descriptor cannot be found: No such type.\r
+  //\r
+  if (Len < Offset) {\r
+    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset, Len));\r
+    return NULL;\r
+  }\r
+\r
+  if ((Head->Type != Type) || (Head->Len < DescLen)) {\r
+    DEBUG ((DEBUG_ERROR, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head->Type, Head->Len));\r
     return NULL;\r
   }\r
 \r
@@ -212,7 +238,7 @@ UsbCreateDesc (
 \r
   CopyMem (Desc, Head, (UINTN) DescLen);\r
 \r
-  *Consumed = Offset + Head->Len;\r
+  *Consumed = Offset;\r
 \r
   return Desc;\r
 }\r
@@ -361,7 +387,7 @@ UsbParseConfigDesc (
   Len     -= Consumed;\r
 \r
   //\r
-  // Make allowances for devices that return extra data at the \r
+  // Make allowances for devices that return extra data at the\r
   // end of their config descriptors\r
   //\r
   while (Len >= sizeof (EFI_USB_INTERFACE_DESCRIPTOR)) {\r
@@ -539,7 +565,7 @@ UsbGetMaxPacketSize0 (
     Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, &DevDesc, 8);\r
 \r
     if (!EFI_ERROR (Status)) {\r
-      if ((DevDesc.BcdUSB == 0x0300) && (DevDesc.MaxPacketSize0 == 9)) {\r
+      if ((DevDesc.BcdUSB >= 0x0300) && (DevDesc.MaxPacketSize0 == 9)) {\r
         UsbDev->MaxPacket0 = 1 << 9;\r
         return EFI_SUCCESS;\r
       }\r
@@ -624,7 +650,13 @@ UsbGetOneString (
   //\r
   Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2);\r
 \r
-  if (EFI_ERROR (Status)) {\r
+  //\r
+  // Reject if Length even cannot cover itself, or odd because Unicode string byte length should be even.\r
+  //\r
+  if (EFI_ERROR (Status) ||\r
+      (Desc.Length < OFFSET_OF (EFI_USB_STRING_DESCRIPTOR, Length) + sizeof (Desc.Length)) ||\r
+      (Desc.Length % 2 != 0)\r
+    ) {\r
     return NULL;\r
   }\r
 \r
@@ -689,7 +721,7 @@ UsbBuildLangTable (
 \r
   Max   = (Desc->Length - 2) / 2;\r
   Max   = MIN(Max, USB_MAX_LANG_ID);\r
-  \r
+\r
   Point = Desc->String;\r
   for (Index = 0; Index < Max; Index++) {\r
     UsbDev->LangId[Index] = *Point;\r
@@ -741,6 +773,13 @@ UsbGetOneConfig (
 \r
   DEBUG (( EFI_D_INFO, "UsbGetOneConfig: total length is %d\n", Desc.TotalLength));\r
 \r
+  //\r
+  // Reject if TotalLength even cannot cover itself.\r
+  //\r
+  if (Desc.TotalLength < OFFSET_OF (EFI_USB_CONFIG_DESCRIPTOR, TotalLength) + sizeof (Desc.TotalLength)) {\r
+    return NULL;\r
+  }\r
+\r
   Buf = AllocateZeroPool (Desc.TotalLength);\r
 \r
   if (Buf == NULL) {\r