NetworkPkg: Fix possible infinite loop in HTTP msg body parser

When an HTTP server sends a non-chunked body data with no
Content-Length header, the HttpParserMessageBody in DxeHttpLib
gets confused and never sets the Char pointer beyond the body start.
This causes "for" loop to never break because the condition of
"Char >= Body + BodyLength" is never satisfied.
Use BodyLength as the ContentLength for the parser when
ContentLength is absent in HTTP response headers.
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=2941

Signed-off-by: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
This commit is contained in:
Vladimir Olovyannikov via groups.io
2020-08-28 11:17:06 -07:00
committed by mergify[bot]
parent 5df413119e
commit 70c2f10fde

View File

@ -1122,6 +1122,7 @@ HttpParseMessageBody (
CHAR8 *Char; CHAR8 *Char;
UINTN RemainderLengthInThis; UINTN RemainderLengthInThis;
UINTN LengthForCallback; UINTN LengthForCallback;
UINTN PortionLength;
EFI_STATUS Status; EFI_STATUS Status;
HTTP_BODY_PARSER *Parser; HTTP_BODY_PARSER *Parser;
@ -1173,19 +1174,31 @@ HttpParseMessageBody (
// //
// Identity transfer-coding, just notify user to save the body data. // Identity transfer-coding, just notify user to save the body data.
// //
PortionLength = MIN (
BodyLength,
Parser->ContentLength - Parser->ParsedBodyLength
);
if (PortionLength == 0) {
//
// Got BodyLength, but no ContentLength. Use BodyLength.
//
PortionLength = BodyLength;
Parser->ContentLength = PortionLength;
}
if (Parser->Callback != NULL) { if (Parser->Callback != NULL) {
Status = Parser->Callback ( Status = Parser->Callback (
BodyParseEventOnData, BodyParseEventOnData,
Char, Char,
MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength), PortionLength,
Parser->Context Parser->Context
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }
} }
Char += MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength); Char += PortionLength;
Parser->ParsedBodyLength += MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength); Parser->ParsedBodyLength += PortionLength;
if (Parser->ParsedBodyLength == Parser->ContentLength) { if (Parser->ParsedBodyLength == Parser->ContentLength) {
Parser->State = BodyParserComplete; Parser->State = BodyParserComplete;
if (Parser->Callback != NULL) { if (Parser->Callback != NULL) {