]> git.proxmox.com Git - mirror_edk2.git/commitdiff
NetworkPkg/HttpDxe: Fix the bug when parsing HTTP(S) message body.
authorJiaxin Wu <Jiaxin.wu@intel.com>
Mon, 2 Jul 2018 01:48:12 +0000 (09:48 +0800)
committerJiaxin Wu <Jiaxin.wu@intel.com>
Thu, 12 Jul 2018 00:37:54 +0000 (08:37 +0800)
*v2: Resolve the conflict commit.

*v3: Fixed the failure if BodyLength in HTTP token is less than the received
size of HTTPS message.

HttpBodyParserCallback function is to parse the HTTP(S) message body so as to
confirm whether there is the next message header. But it doesn't record the
parsing message data/length correctly.

This patch is refine the parsing logic so as to fix the potential failure.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Gary Lin <glin@suse.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Tested-by: Gary Lin <glin@suse.com>
NetworkPkg/HttpDxe/HttpImpl.c
NetworkPkg/HttpDxe/HttpProto.c
NetworkPkg/HttpDxe/HttpProto.h

index f70e116f38d7e78f7bfc131c343b26aa4bc622bc..17deceb395473e7457e2c3616c7059eea423cc56 100644 (file)
@@ -916,6 +916,7 @@ HttpBodyParserCallback (
   IN VOID                       *Context\r
   )\r
 {\r
   IN VOID                       *Context\r
   )\r
 {\r
+  HTTP_CALLBACK_DATA            *CallbackData;\r
   HTTP_TOKEN_WRAP               *Wrap;\r
   UINTN                         BodyLength;\r
   CHAR8                         *Body;\r
   HTTP_TOKEN_WRAP               *Wrap;\r
   UINTN                         BodyLength;\r
   CHAR8                         *Body;\r
@@ -928,21 +929,18 @@ HttpBodyParserCallback (
     return EFI_SUCCESS;\r
   }\r
 \r
     return EFI_SUCCESS;\r
   }\r
 \r
-  Wrap = (HTTP_TOKEN_WRAP *) Context;\r
-  Body = Wrap->HttpToken->Message->Body;\r
-  BodyLength = Wrap->HttpToken->Message->BodyLength;\r
+  CallbackData = (HTTP_CALLBACK_DATA *) Context;\r
+\r
+  Wrap       = (HTTP_TOKEN_WRAP *) (CallbackData->Wrap);\r
+  Body       = CallbackData->ParseData;\r
+  BodyLength = CallbackData->ParseDataLength;\r
+\r
   if (Data < Body + BodyLength) {\r
     Wrap->HttpInstance->NextMsg = Data;\r
   } else {\r
     Wrap->HttpInstance->NextMsg = NULL;\r
   }\r
 \r
   if (Data < Body + BodyLength) {\r
     Wrap->HttpInstance->NextMsg = Data;\r
   } else {\r
     Wrap->HttpInstance->NextMsg = NULL;\r
   }\r
 \r
-\r
-  //\r
-  // Free Tx4Token or Tx6Token since already received corrsponding HTTP response.\r
-  //\r
-  FreePool (Wrap);\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1191,7 +1189,7 @@ HttpResponseWorker (
                  HttpMsg->HeaderCount,\r
                  HttpMsg->Headers,\r
                  HttpBodyParserCallback,\r
                  HttpMsg->HeaderCount,\r
                  HttpMsg->Headers,\r
                  HttpBodyParserCallback,\r
-                 (VOID *) ValueInItem,\r
+                 (VOID *) (&HttpInstance->CallbackData),\r
                  &HttpInstance->MsgParser\r
                  );\r
       if (EFI_ERROR (Status)) {\r
                  &HttpInstance->MsgParser\r
                  );\r
       if (EFI_ERROR (Status)) {\r
@@ -1202,18 +1200,28 @@ HttpResponseWorker (
       // Check whether we received a complete HTTP message.\r
       //\r
       if (HttpInstance->CacheBody != NULL) {\r
       // Check whether we received a complete HTTP message.\r
       //\r
       if (HttpInstance->CacheBody != NULL) {\r
+        //\r
+        // Record the CallbackData data.\r
+        //\r
+        HttpInstance->CallbackData.Wrap = (VOID *) Wrap;\r
+        HttpInstance->CallbackData.ParseData = (VOID *) HttpInstance->CacheBody;\r
+        HttpInstance->CallbackData.ParseDataLength = HttpInstance->CacheLen;\r
+\r
+        //\r
+        // Parse message with CallbackData data.\r
+        //\r
         Status = HttpParseMessageBody (HttpInstance->MsgParser, HttpInstance->CacheLen, HttpInstance->CacheBody);\r
         if (EFI_ERROR (Status)) {\r
           goto Error2;\r
         }\r
         Status = HttpParseMessageBody (HttpInstance->MsgParser, HttpInstance->CacheLen, HttpInstance->CacheBody);\r
         if (EFI_ERROR (Status)) {\r
           goto Error2;\r
         }\r
+      }\r
 \r
 \r
-        if (HttpIsMessageComplete (HttpInstance->MsgParser)) {\r
-          //\r
-          // Free the MsgParse since we already have a full HTTP message.\r
-          //\r
-          HttpFreeMsgParser (HttpInstance->MsgParser);\r
-          HttpInstance->MsgParser = NULL;\r
-        }\r
+      if (HttpIsMessageComplete (HttpInstance->MsgParser)) {\r
+        //\r
+        // Free the MsgParse since we already have a full HTTP message.\r
+        //\r
+        HttpFreeMsgParser (HttpInstance->MsgParser);\r
+        HttpInstance->MsgParser = NULL;\r
       }\r
     }\r
 \r
       }\r
     }\r
 \r
@@ -1332,12 +1340,26 @@ HttpResponseWorker (
     }\r
 \r
     //\r
     }\r
 \r
     //\r
-    // Check whether we receive a complete HTTP message.\r
+    // Process the received the body packet.\r
+    //\r
+    HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);\r
+\r
+    CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
+\r
+    //\r
+    // Record the CallbackData data.\r
+    //\r
+    HttpInstance->CallbackData.Wrap = (VOID *) Wrap;\r
+    HttpInstance->CallbackData.ParseData = HttpMsg->Body;\r
+    HttpInstance->CallbackData.ParseDataLength = HttpMsg->BodyLength;\r
+\r
+    //\r
+    // Parse Body with CallbackData data.\r
     //\r
     Status = HttpParseMessageBody (\r
                HttpInstance->MsgParser,\r
     //\r
     Status = HttpParseMessageBody (\r
                HttpInstance->MsgParser,\r
-               (UINTN) Fragment.Len,\r
-               (CHAR8 *) Fragment.Bulk\r
+               HttpMsg->BodyLength,\r
+               HttpMsg->Body\r
                );\r
     if (EFI_ERROR (Status)) {\r
       goto Error2;\r
                );\r
     if (EFI_ERROR (Status)) {\r
       goto Error2;\r
@@ -1352,46 +1374,28 @@ HttpResponseWorker (
     }\r
 \r
     //\r
     }\r
 \r
     //\r
-    // We receive part of header of next HTTP msg.\r
+    // Check whether there is the next message header in the HttpMsg->Body.\r
     //\r
     if (HttpInstance->NextMsg != NULL) {\r
     //\r
     if (HttpInstance->NextMsg != NULL) {\r
-      HttpMsg->BodyLength = MIN ((UINTN) HttpInstance->NextMsg - (UINTN) Fragment.Bulk, HttpMsg->BodyLength);\r
-      CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
-\r
-      HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
-      if (HttpInstance->CacheLen != 0) {\r
-        if (HttpInstance->CacheBody != NULL) {\r
-          FreePool (HttpInstance->CacheBody);\r
-        }\r
-\r
-        HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
-        if (HttpInstance->CacheBody == NULL) {\r
-          Status = EFI_OUT_OF_RESOURCES;\r
-          goto Error2;\r
-        }\r
-\r
-        CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
-        HttpInstance->CacheOffset = 0;\r
+      HttpMsg->BodyLength = HttpInstance->NextMsg - (CHAR8 *) HttpMsg->Body;\r
+    }\r
 \r
 \r
-        HttpInstance->NextMsg = HttpInstance->CacheBody + ((UINTN) HttpInstance->NextMsg - (UINTN) (Fragment.Bulk + HttpMsg->BodyLength));\r
+    HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
+    if (HttpInstance->CacheLen != 0) {\r
+      if (HttpInstance->CacheBody != NULL) {\r
+        FreePool (HttpInstance->CacheBody);\r
       }\r
       }\r
-    } else {\r
-      HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);\r
-      CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);\r
-      HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;\r
-      if (HttpInstance->CacheLen != 0) {\r
-        if (HttpInstance->CacheBody != NULL) {\r
-          FreePool (HttpInstance->CacheBody);\r
-        }\r
 \r
 \r
-        HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
-        if (HttpInstance->CacheBody == NULL) {\r
-          Status = EFI_OUT_OF_RESOURCES;\r
-          goto Error2;\r
-        }\r
+      HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);\r
+      if (HttpInstance->CacheBody == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Error2;\r
+      }\r
 \r
 \r
-        CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
-        HttpInstance->CacheOffset = 0;\r
+      CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);\r
+      HttpInstance->CacheOffset = 0;\r
+      if (HttpInstance->NextMsg != NULL) {\r
+        HttpInstance->NextMsg = HttpInstance->CacheBody;\r
       }\r
     }\r
 \r
       }\r
     }\r
 \r
index 5356cd35c0f3d972bf987aad0cc8d36ed61aa2a5..94f89f5665846049c0aafbf471d18463d186d84e 100644 (file)
@@ -197,6 +197,16 @@ HttpTcpReceiveNotifyDpc (
     Length = (UINTN) Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;\r
   }\r
 \r
     Length = (UINTN) Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;\r
   }\r
 \r
+  //\r
+  // Record the CallbackData data.\r
+  //\r
+  HttpInstance->CallbackData.Wrap = (VOID *) Wrap;\r
+  HttpInstance->CallbackData.ParseData = Wrap->HttpToken->Message->Body;\r
+  HttpInstance->CallbackData.ParseDataLength = Length;\r
+\r
+  //\r
+  // Parse Body with CallbackData data.\r
+  //\r
   Status = HttpParseMessageBody (\r
              HttpInstance->MsgParser,\r
              Length,\r
   Status = HttpParseMessageBody (\r
              HttpInstance->MsgParser,\r
              Length,\r
index cc6c1eb566debcb3359466b7c1987e2565c22337..fa57dbfd39d9de12cadcddd6d0e0d552def92fe9 100644 (file)
@@ -91,6 +91,15 @@ typedef struct {
   EFI_TLS_SESSION_STATE         SessionState;\r
 } TLS_CONFIG_DATA;\r
 \r
   EFI_TLS_SESSION_STATE         SessionState;\r
 } TLS_CONFIG_DATA;\r
 \r
+//\r
+// Callback data for HTTP_PARSER_CALLBACK()\r
+//\r
+typedef struct {\r
+  UINTN                         ParseDataLength;\r
+  VOID                          *ParseData;\r
+  VOID                          *Wrap;\r
+} HTTP_CALLBACK_DATA;\r
+\r
 typedef struct _HTTP_PROTOCOL {\r
   UINT32                        Signature;\r
   EFI_HTTP_PROTOCOL             Http;\r
 typedef struct _HTTP_PROTOCOL {\r
   UINT32                        Signature;\r
   EFI_HTTP_PROTOCOL             Http;\r
@@ -149,6 +158,7 @@ typedef struct _HTTP_PROTOCOL {
   // HTTP message-body parser.\r
   //\r
   VOID                          *MsgParser;\r
   // HTTP message-body parser.\r
   //\r
   VOID                          *MsgParser;\r
+  HTTP_CALLBACK_DATA            CallbackData;\r
 \r
   EFI_HTTP_VERSION              HttpVersion;\r
   UINT32                        TimeOutMillisec;\r
 \r
   EFI_HTTP_VERSION              HttpVersion;\r
   UINT32                        TimeOutMillisec;\r