]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/TcpDxe/TcpInput.c
NetworkPkg: Fix potential ASSERT if NetIp4IsUnicast is called
[mirror_edk2.git] / NetworkPkg / TcpDxe / TcpInput.c
index e63469adb9e3f9c1d5b6fcd1d3ee736652b141d6..04c8a8269ea704b1a2b8593455ff394097217349 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   TCP input process routines.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -31,7 +31,7 @@ TcpSeqAcceptable (
   IN TCP_SEG *Seg\r
   )\r
 {\r
-  return (TCP_SEQ_LEQ (Tcb->RcvWl2, Seg->End) &&\r
+  return (TCP_SEQ_LEQ (Tcb->RcvNxt, Seg->End) &&\r
           TCP_SEQ_LT (Seg->Seq, Tcb->RcvWl2 + Tcb->RcvWnd));\r
 }\r
 \r
@@ -74,7 +74,7 @@ TcpFastRecover (
     Tcb->CWnd = Tcb->Ssthresh + 3 * Tcb->SndMss;\r
 \r
     DEBUG (\r
-      (EFI_D_INFO,\r
+      (EFI_D_NET,\r
       "TcpFastRecover: enter fast retransmission for TCB %p, recover point is %d\n",\r
       Tcb,\r
       Tcb->Recover)\r
@@ -97,7 +97,7 @@ TcpFastRecover (
     //\r
     Tcb->CWnd += Tcb->SndMss;\r
     DEBUG (\r
-      (EFI_D_INFO,\r
+      (EFI_D_NET,\r
       "TcpFastRecover: received another duplicated ACK (%d) for TCB %p\n",\r
       Seg->Ack,\r
       Tcb)\r
@@ -121,7 +121,7 @@ TcpFastRecover (
 \r
       Tcb->CongestState = TCP_CONGEST_OPEN;\r
       DEBUG (\r
-        (EFI_D_INFO,\r
+        (EFI_D_NET,\r
         "TcpFastRecover: received a full ACK(%d) for TCB %p, exit fast recovery\n",\r
         Seg->Ack,\r
         Tcb)\r
@@ -150,7 +150,7 @@ TcpFastRecover (
       Tcb->CWnd -= Acked;\r
 \r
       DEBUG (\r
-        (EFI_D_INFO,\r
+        (EFI_D_NET,\r
         "TcpFastRecover: received a partial ACK(%d) for TCB %p\n",\r
         Seg->Ack,\r
         Tcb)\r
@@ -188,7 +188,7 @@ TcpFastLossRecover (
       Tcb->CongestState = TCP_CONGEST_OPEN;\r
 \r
       DEBUG (\r
-        (EFI_D_INFO,\r
+        (EFI_D_NET,\r
         "TcpFastLossRecover: received a full ACK(%d) for TCB %p\n",\r
         Seg->Ack,\r
         Tcb)\r
@@ -202,7 +202,7 @@ TcpFastLossRecover (
       //\r
       TcpRetransmit (Tcb, Seg->Ack);\r
       DEBUG (\r
-        (EFI_D_INFO,\r
+        (EFI_D_NET,\r
         "TcpFastLossRecover: received a partial ACK(%d) for TCB %p\n",\r
         Seg->Ack,\r
         Tcb)\r
@@ -264,7 +264,7 @@ TcpComputeRtt (
   }\r
 \r
   DEBUG (\r
-    (EFI_D_INFO,\r
+    (EFI_D_NET,\r
     "TcpComputeRtt: new RTT for TCB %p computed SRTT: %d RTTVAR: %d RTO: %d\n",\r
     Tcb,\r
     Tcb->SRtt,\r
@@ -455,7 +455,7 @@ TcpDeliverData (
       }\r
 \r
       DEBUG (\r
-        (EFI_D_INFO,\r
+        (EFI_D_NET,\r
         "TcpDeliverData: processing FIN from peer of TCB %p\n",\r
         Tcb)\r
         );\r
@@ -531,8 +531,8 @@ TcpDeliverData (
       Urgent = 0;\r
 \r
       if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_URG) &&\r
-          TCP_SEQ_LEQ (Seg->Seq, Tcb->RcvUp)\r
-          ) {\r
+          TCP_SEQ_LEQ (Seg->Seq, Tcb->RcvUp))\r
+      {\r
 \r
         if (TCP_SEQ_LEQ (Seg->End, Tcb->RcvUp)) {\r
           Urgent = Nbuf->TotalSize;\r
@@ -596,8 +596,7 @@ TcpQueueData (
   //\r
   for (Prev = Head, Cur = Head->ForwardLink;\r
        Cur != Head;\r
-       Prev = Cur, Cur = Cur->ForwardLink\r
-       ) {\r
+       Prev = Cur, Cur = Cur->ForwardLink) {\r
 \r
     Node = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);\r
 \r
@@ -749,11 +748,18 @@ TcpInput (
 \r
   Head    = (TCP_HEAD *) NetbufGetByte (Nbuf, 0, NULL);\r
   ASSERT (Head != NULL);\r
+  \r
+  if (Nbuf->TotalSize < sizeof (TCP_HEAD)) {\r
+    DEBUG ((EFI_D_NET, "TcpInput: received a malformed packet\n"));\r
+    goto DISCARD;\r
+  }\r
+  \r
   Len     = Nbuf->TotalSize - (Head->HeadLen << 2);\r
 \r
   if ((Head->HeadLen < 5) || (Len < 0)) {\r
 \r
-    DEBUG ((EFI_D_INFO, "TcpInput: received an mal-formated packet\n"));\r
+    DEBUG ((EFI_D_NET, "TcpInput: received a malformed packet\n"));\r
+    \r
     goto DISCARD;\r
   }\r
 \r
@@ -788,7 +794,7 @@ TcpInput (
           );\r
 \r
   if ((Tcb == NULL) || (Tcb->State == TCP_CLOSED)) {\r
-    DEBUG ((EFI_D_INFO, "TcpInput: send reset because no TCB find\n"));\r
+    DEBUG ((EFI_D_NET, "TcpInput: send reset because no TCB found\n"));\r
 \r
     Tcb = NULL;\r
     goto SEND_RESET;\r
@@ -803,7 +809,7 @@ TcpInput (
   if (TcpParseOption (Nbuf->Tcp, &Option) == -1) {\r
     DEBUG (\r
       (EFI_D_ERROR,\r
-      "TcpInput: reset the peer because of mal-format option for Tcb %p\n",\r
+      "TcpInput: reset the peer because of malformed option for TCB %p\n",\r
       Tcb)\r
       );\r
 \r
@@ -860,7 +866,7 @@ TcpInput (
       if (Tcb == NULL) {\r
         DEBUG (\r
           (EFI_D_ERROR,\r
-          "TcpInput: discard a segment because failed to clone a child for TCB%p\n",\r
+          "TcpInput: discard a segment because failed to clone a child for TCB %p\n",\r
           Tcb)\r
           );\r
 \r
@@ -868,7 +874,7 @@ TcpInput (
       }\r
 \r
       DEBUG (\r
-        (EFI_D_INFO,\r
+        (EFI_D_NET,\r
         "TcpInput: create a child for TCB %p in listening\n",\r
         Tcb)\r
         );\r
@@ -940,7 +946,7 @@ TcpInput (
     //\r
 \r
     //\r
-    // Fourth step: Check SYN. Pay attention to sitimulatous open\r
+    // Fourth step: Check SYN. Pay attention to simultaneous open\r
     //\r
     if (TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN)) {\r
 \r
@@ -961,8 +967,8 @@ TcpInput (
         TcpDeliverData (Tcb);\r
 \r
         if ((Tcb->CongestState == TCP_CONGEST_OPEN) &&\r
-            TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RTT_ON)\r
-            ) {\r
+            TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RTT_ON))\r
+        {\r
 \r
           TcpComputeRtt (Tcb, Tcb->RttMeasure);\r
           TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_RTT_ON);\r
@@ -973,7 +979,7 @@ TcpInput (
         TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_ACK_NOW);\r
 \r
         DEBUG (\r
-          (EFI_D_INFO,\r
+          (EFI_D_NET,\r
           "TcpInput: connection established for TCB %p in SYN_SENT\n",\r
           Tcb)\r
           );\r
@@ -992,7 +998,7 @@ TcpInput (
 \r
         DEBUG (\r
           (EFI_D_WARN,\r
-          "TcpInput: simultanous open for TCB %p in SYN_SENT\n",\r
+          "TcpInput: simultaneous open for TCB %p in SYN_SENT\n",\r
           Tcb)\r
           );\r
 \r
@@ -1034,8 +1040,8 @@ TcpInput (
 \r
   if ((TCP_SEQ_LT (Seg->Seq, Tcb->RcvWl2)) &&\r
       (Tcb->RcvWl2 == Seg->End) &&\r
-      !TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN | TCP_FLG_FIN)\r
-        ) {\r
+      !TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN | TCP_FLG_FIN))\r
+  {\r
 \r
     TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_ACK_NOW);\r
   }\r
@@ -1058,10 +1064,10 @@ TcpInput (
       // if it comes from a LISTEN TCB.\r
       //\r
     } else if ((Tcb->State == TCP_ESTABLISHED) ||\r
-             (Tcb->State == TCP_FIN_WAIT_1) ||\r
-             (Tcb->State == TCP_FIN_WAIT_2) ||\r
-             (Tcb->State == TCP_CLOSE_WAIT)\r
-            ) {\r
+               (Tcb->State == TCP_FIN_WAIT_1) ||\r
+               (Tcb->State == TCP_FIN_WAIT_2) ||\r
+               (Tcb->State == TCP_CLOSE_WAIT))\r
+    {\r
 \r
       SOCK_ERROR (Tcb->Sk, EFI_CONNECTION_RESET);\r
 \r
@@ -1114,7 +1120,9 @@ TcpInput (
 \r
   if (Tcb->State == TCP_SYN_RCVD) {\r
 \r
-    if (TCP_SEQ_LT (Tcb->SndUna, Seg->Ack) && TCP_SEQ_LEQ (Seg->Ack, Tcb->SndNxt)) {\r
+    if (TCP_SEQ_LT (Tcb->SndUna, Seg->Ack) &&\r
+        TCP_SEQ_LEQ (Seg->Ack, Tcb->SndNxt))\r
+    {\r
 \r
       Tcb->SndWnd     = Seg->Wnd;\r
       Tcb->SndWndMax  = MAX (Tcb->SndWnd, Tcb->SndWndMax);\r
@@ -1126,8 +1134,8 @@ TcpInput (
       TcpDeliverData (Tcb);\r
 \r
       DEBUG (\r
-        (EFI_D_INFO,\r
-        "TcpInput: connection established  for TCB %p in SYN_RCVD\n",\r
+        (EFI_D_NET,\r
+        "TcpInput: connection established for TCB %p in SYN_RCVD\n",\r
         Tcb)\r
         );\r
 \r
@@ -1176,7 +1184,9 @@ TcpInput (
     // RcvWl2 equals to the variable "LastAckSent"\r
     // defined there.\r
     //\r
-    if (TCP_SEQ_LEQ (Seg->Seq, Tcb->RcvWl2) && TCP_SEQ_LT (Tcb->RcvWl2, Seg->End)) {\r
+    if (TCP_SEQ_LEQ (Seg->Seq, Tcb->RcvWl2) &&\r
+        TCP_SEQ_LT (Tcb->RcvWl2, Seg->End))\r
+    {\r
 \r
       Tcb->TsRecent     = Option.TSVal;\r
       Tcb->TsRecentAge  = mTcpTick;\r
@@ -1206,8 +1216,8 @@ TcpInput (
   if ((Seg->Ack == Tcb->SndUna) &&\r
       (Tcb->SndUna != Tcb->SndNxt) &&\r
       (Seg->Wnd == Tcb->SndWnd) &&\r
-      (0 == Len)\r
-      ) {\r
+      (0 == Len))\r
+  {\r
 \r
     Tcb->DupAck++;\r
   } else {\r
@@ -1219,8 +1229,8 @@ TcpInput (
   // Congestion avoidance, fast recovery and fast retransmission.\r
   //\r
   if (((Tcb->CongestState == TCP_CONGEST_OPEN) && (Tcb->DupAck < 3)) ||\r
-      (Tcb->CongestState == TCP_CONGEST_LOSS)\r
-      ) {\r
+      (Tcb->CongestState == TCP_CONGEST_LOSS))\r
+  {\r
 \r
     if (TCP_SEQ_GT (Seg->Ack, Tcb->SndUna)) {\r
 \r
@@ -1249,8 +1259,8 @@ TcpInput (
     Tcb->SndUna = Seg->Ack;\r
 \r
     if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_SND_URG) &&\r
-        TCP_SEQ_LT (Tcb->SndUp, Seg->Ack)\r
-        ) {\r
+        TCP_SEQ_LT (Tcb->SndUp, Seg->Ack))\r
+    {\r
 \r
       TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);\r
     }\r
@@ -1260,8 +1270,8 @@ TcpInput (
   // Update window info\r
   //\r
   if (TCP_SEQ_LT (Tcb->SndWl1, Seg->Seq) ||\r
-      ((Tcb->SndWl1 == Seg->Seq) && TCP_SEQ_LEQ (Tcb->SndWl2, Seg->Ack))\r
-      ) {\r
+      ((Tcb->SndWl1 == Seg->Seq) && TCP_SEQ_LEQ (Tcb->SndWl2, Seg->Ack)))\r
+  {\r
 \r
     Right = Seg->Ack + Seg->Wnd;\r
 \r
@@ -1269,8 +1279,8 @@ TcpInput (
 \r
       if ((Tcb->SndWl1 == Seg->Seq) &&\r
           (Tcb->SndWl2 == Seg->Ack) &&\r
-          (Len == 0)\r
-          ) {\r
+          (Len == 0))\r
+      {\r
 \r
         goto NO_UPDATE;\r
       }\r
@@ -1281,12 +1291,16 @@ TcpInput (
         Tcb)\r
         );\r
 \r
-      if ((Tcb->CongestState == TCP_CONGEST_RECOVER) && (TCP_SEQ_LT (Right, Tcb->Recover))) {\r
+      if ((Tcb->CongestState == TCP_CONGEST_RECOVER) &&\r
+          (TCP_SEQ_LT (Right, Tcb->Recover)))\r
+      {\r
 \r
         Tcb->Recover = Right;\r
       }\r
 \r
-      if ((Tcb->CongestState == TCP_CONGEST_LOSS) && (TCP_SEQ_LT (Right, Tcb->LossRecover))) {\r
+      if ((Tcb->CongestState == TCP_CONGEST_LOSS) &&\r
+          (TCP_SEQ_LT (Right, Tcb->LossRecover)))\r
+      {\r
 \r
         Tcb->LossRecover = Right;\r
       }\r
@@ -1311,10 +1325,12 @@ TcpInput (
 \r
 NO_UPDATE:\r
 \r
-  if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_SENT) && (Tcb->SndUna == Tcb->SndNxt)) {\r
+  if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_FIN_SENT) &&\r
+      (Tcb->SndUna == Tcb->SndNxt))\r
+  {\r
 \r
     DEBUG (\r
-      (EFI_D_INFO,\r
+      (EFI_D_NET,\r
       "TcpInput: local FIN is ACKed by peer for connected TCB %p\n",\r
       Tcb)\r
       );\r
@@ -1410,14 +1426,16 @@ StepSix:
   if (TCP_FLG_ON (Seg->Flag, TCP_FLG_URG) && !TCP_FIN_RCVD (Tcb->State)) {\r
 \r
     DEBUG (\r
-      (EFI_D_INFO,\r
+      (EFI_D_NET,\r
       "TcpInput: received urgent data from peer for connected TCB %p\n",\r
       Tcb)\r
       );\r
 \r
     Urg = Seg->Seq + Seg->Urg;\r
 \r
-    if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_URG) && TCP_SEQ_GT (Urg, Tcb->RcvUp)) {\r
+    if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RCVD_URG) &&\r
+        TCP_SEQ_GT (Urg, Tcb->RcvUp))\r
+    {\r
 \r
       Tcb->RcvUp = Urg;\r
     } else {\r
@@ -1480,8 +1498,8 @@ StepSix:
 \r
   if ((Tcb->State != TCP_CLOSED) &&\r
       (TcpToSendData (Tcb, 0) == 0) &&\r
-      (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_ACK_NOW) || (Nbuf->TotalSize != 0))\r
-      ) {\r
+      (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_ACK_NOW) || (Nbuf->TotalSize != 0)))\r
+  {\r
 \r
     TcpToSendAck (Tcb);\r
   }\r
@@ -1549,6 +1567,10 @@ TcpIcmpInput (
   BOOLEAN          IcmpErrIsHard;\r
   BOOLEAN          IcmpErrNotify;\r
 \r
+  if (Nbuf->TotalSize < sizeof (TCP_HEAD)) {\r
+    goto CLEAN_EXIT;\r
+  }\r
+  \r
   Head = (TCP_HEAD *) NetbufGetByte (Nbuf, 0, NULL);\r
   ASSERT (Head != NULL);\r
 \r
@@ -1574,7 +1596,12 @@ TcpIcmpInput (
     goto CLEAN_EXIT;\r
   }\r
 \r
-  IcmpErrStatus = IpIoGetIcmpErrStatus (IcmpErr, Tcb->Sk->IpVersion, &IcmpErrIsHard, &IcmpErrNotify);\r
+  IcmpErrStatus = IpIoGetIcmpErrStatus (\r
+                    IcmpErr,\r
+                    Tcb->Sk->IpVersion,\r
+                    &IcmpErrIsHard,\r
+                    &IcmpErrNotify\r
+                    );\r
 \r
   if (IcmpErrNotify) {\r
 \r