mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/UsbBus: Fix out-of-bound read access to descriptors
Today's implementation reads the Type/Length field in the USB descriptors data without checking whether the offset to read is beyond the data boundary. The patch fixes this issue. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
parent
4f8b2f9d72
commit
4c034bf62c
|
@ -177,6 +177,18 @@ UsbCreateDesc (
|
||||||
DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);
|
DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);
|
||||||
CtrlLen = sizeof (USB_ENDPOINT_DESC);
|
CtrlLen = sizeof (USB_ENDPOINT_DESC);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Total length is too small that cannot hold the single descriptor header plus data.
|
||||||
|
//
|
||||||
|
if (Len <= sizeof (USB_DESC_HEAD)) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, total length = %d!\n", Len));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -185,23 +197,42 @@ UsbCreateDesc (
|
||||||
//
|
//
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
Head = (USB_DESC_HEAD *)DescBuf;
|
Head = (USB_DESC_HEAD *)DescBuf;
|
||||||
|
while (Offset < Len - sizeof (USB_DESC_HEAD)) {
|
||||||
|
//
|
||||||
|
// Above condition make sure Head->Len and Head->Type are safe to access
|
||||||
|
//
|
||||||
|
Head = (USB_DESC_HEAD *)&DescBuf[Offset];
|
||||||
|
|
||||||
while ((Offset < Len) && (Head->Type != Type)) {
|
|
||||||
Offset += Head->Len;
|
|
||||||
if (Len <= Offset) {
|
|
||||||
DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Beyond boundary!\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Head = (USB_DESC_HEAD*)(DescBuf + Offset);
|
|
||||||
if (Head->Len == 0) {
|
if (Head->Len == 0) {
|
||||||
DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
|
DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = 0!\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure no overflow when adding Head->Len to Offset.
|
||||||
|
//
|
||||||
|
if (Head->Len > MAX_UINTN - Offset) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Head->Len = %d!\n", Head->Len));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset += Head->Len;
|
||||||
|
|
||||||
|
if (Head->Type == Type) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Len <= Offset) || (Len < Offset + Head->Len) ||
|
//
|
||||||
(Head->Type != Type) || (Head->Len < DescLen)) {
|
// Head->Len is invalid resulting data beyond boundary, or
|
||||||
DEBUG (( EFI_D_ERROR, "UsbCreateDesc: met mal-format descriptor\n"));
|
// Descriptor cannot be found: No such type.
|
||||||
|
//
|
||||||
|
if (Len < Offset) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "UsbCreateDesc: met mal-format descriptor, Offset/Len = %d/%d!\n", Offset, Len));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Head->Type != Type) || (Head->Len < DescLen)) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "UsbCreateDesc: descriptor cannot be found, Header(T/L) = %d/%d!\n", Head->Type, Head->Len));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +243,7 @@ UsbCreateDesc (
|
||||||
|
|
||||||
CopyMem (Desc, Head, (UINTN) DescLen);
|
CopyMem (Desc, Head, (UINTN) DescLen);
|
||||||
|
|
||||||
*Consumed = Offset + Head->Len;
|
*Consumed = Offset;
|
||||||
|
|
||||||
return Desc;
|
return Desc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue