\r
Manage Usb Descriptor List\r
\r
-Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2007 - 2018, 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
VOID *\r
UsbCreateDesc (\r
IN UINT8 *DescBuf,\r
- IN INTN Len,\r
+ IN UINTN Len,\r
IN UINT8 Type,\r
- OUT INTN *Consumed\r
+ OUT UINTN *Consumed\r
)\r
{\r
USB_DESC_HEAD *Head;\r
- INTN DescLen;\r
- INTN CtrlLen;\r
- INTN Offset;\r
+ UINTN DescLen;\r
+ UINTN CtrlLen;\r
+ UINTN Offset;\r
VOID *Desc;\r
\r
DescLen = 0;\r
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
// 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
+ if (Head->Len == 0) {\r
+ DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));\r
+ return NULL;\r
+ }\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
- while ((Offset < Len) && (Head->Type != Type)) {\r
Offset += Head->Len;\r
- Head = (USB_DESC_HEAD*)(DescBuf + Offset);\r
+\r
+ if (Head->Type == Type) {\r
+ break;\r
+ }\r
+ }\r
+\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
}\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
+ 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
\r
CopyMem (Desc, Head, (UINTN) DescLen);\r
\r
- *Consumed = Offset + Head->Len;\r
+ *Consumed = Offset;\r
\r
return Desc;\r
}\r
USB_INTERFACE_SETTING *\r
UsbParseInterfaceDesc (\r
IN UINT8 *DescBuf,\r
- IN INTN Len,\r
- OUT INTN *Consumed\r
+ IN UINTN Len,\r
+ OUT UINTN *Consumed\r
)\r
{\r
USB_INTERFACE_SETTING *Setting;\r
USB_ENDPOINT_DESC *Ep;\r
UINTN Index;\r
UINTN NumEp;\r
- INTN Used;\r
- INTN Offset;\r
+ UINTN Used;\r
+ UINTN Offset;\r
\r
*Consumed = 0;\r
Setting = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);\r
//\r
// Create the endpoints for this interface\r
//\r
- for (Index = 0; Index < NumEp; Index++) {\r
+ for (Index = 0; (Index < NumEp) && (Offset < Len); Index++) {\r
Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);\r
\r
if (Ep == NULL) {\r
USB_CONFIG_DESC *\r
UsbParseConfigDesc (\r
IN UINT8 *DescBuf,\r
- IN INTN Len\r
+ IN UINTN Len\r
)\r
{\r
USB_CONFIG_DESC *Config;\r
USB_INTERFACE_DESC *Interface;\r
UINTN Index;\r
UINTN NumIf;\r
- INTN Consumed;\r
+ UINTN Consumed;\r
\r
ASSERT (DescBuf != NULL);\r
\r
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
Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed);\r
\r
if (Setting == NULL) {\r
- DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: failed to parse interface setting\n"));\r
- goto ON_ERROR;\r
+ DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: warning: failed to get interface setting, stop parsing now.\n"));\r
+ break;\r
\r
} else if (Setting->Desc.InterfaceNumber >= NumIf) {\r
DEBUG (( EFI_D_ERROR, "UsbParseConfigDesc: mal-formated interface descriptor\n"));\r
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
\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
\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
return Status;\r
}\r
\r
- DevDesc = UsbDev->DevDesc;\r
- NumConfig = DevDesc->Desc.NumConfigurations;\r
- DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));\r
+ DevDesc = UsbDev->DevDesc;\r
+ NumConfig = DevDesc->Desc.NumConfigurations;\r
+ if (NumConfig == 0) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
\r
+ DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));\r
if (DevDesc->Configs == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
Status = UsbBuildLangTable (UsbDev);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG (( EFI_D_ERROR, "UsbBuildDescTable: get language ID table %r\n", Status));\r
+ DEBUG (( EFI_D_INFO, "UsbBuildDescTable: get language ID table %r\n", Status));\r
}\r
\r
return EFI_SUCCESS;\r