From: "Ye, Ting" <ting.ye@intel.com>
To: "Wu, Jiaxin" <jiaxin.wu@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Cc: "Fu, Siyuan" <siyuan.fu@intel.com>, "Wang, Fan" <fan.wang@intel.com>
Subject: Re: [Patch 3/3] NetworkPkg/TcpDxe: Check TCP payload for release version.
Date: Wed, 27 Dec 2017 03:11:05 +0000 [thread overview]
Message-ID: <BC0C045B0E2A584CA4575E779FA2C12A1A987DE0@SHSMSX103.ccr.corp.intel.com> (raw)
In-Reply-To: <1514271011-9780-1-git-send-email-jiaxin.wu@intel.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: Tuesday, December 26, 2017 2:50 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Wang, Fan <fan.wang@intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 3/3] NetworkPkg/TcpDxe: Check TCP payload for release version.
TCP payload check is implemented by TcpVerifySegment(), but all the function calls of TcpVerifySegment() are placed in ASSERT(), which is only valid for debug version:
ASSERT (TcpVerifySegment (Nbuf) != 0);
This patch is to enable the check for release version.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Wang Fan <fan.wang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/TcpDxe/TcpInput.c | 125 +++++++++++++++++++++++++++++++++---------
NetworkPkg/TcpDxe/TcpOutput.c | 29 +++++++---
2 files changed, 122 insertions(+), 32 deletions(-)
diff --git a/NetworkPkg/TcpDxe/TcpInput.c b/NetworkPkg/TcpDxe/TcpInput.c index f8845dc..92a0ab8 100644
--- a/NetworkPkg/TcpDxe/TcpInput.c
+++ b/NetworkPkg/TcpDxe/TcpInput.c
@@ -279,12 +279,15 @@ TcpComputeRtt (
@param[in] Nbuf The buffer that contains a received TCP segment without an IP header.
@param[in] Left The sequence number of the window's left edge.
@param[in] Right The sequence number of the window's right edge.
+ @retval 0 The segment is broken.
+ @retval 1 The segment is in good shape.
+
**/
-VOID
+INTN
TcpTrimSegment (
IN NET_BUF *Nbuf,
IN TCP_SEQNO Left,
IN TCP_SEQNO Right
)
@@ -304,11 +307,11 @@ TcpTrimSegment (
TCP_CLEAR_FLG (Seg->Flag, TCP_FLG_SYN);
TCP_CLEAR_FLG (Seg->Flag, TCP_FLG_FIN);
Seg->Seq = Seg->End;
NetbufTrim (Nbuf, Nbuf->TotalSize, NET_BUF_HEAD);
- return;
+ return 1;
}
//
// Adjust the buffer header
//
@@ -357,27 +360,30 @@ TcpTrimSegment (
if (Drop != 0) {
NetbufTrim (Nbuf, Drop, NET_BUF_TAIL);
}
}
- ASSERT (TcpVerifySegment (Nbuf) != 0);
+ return TcpVerifySegment (Nbuf);
}
/**
Trim off the data outside the tcb's receive window.
@param[in] Tcb Pointer to the TCP_CB of this TCP instance.
@param[in] Nbuf Pointer to the NET_BUF containing the received tcp segment.
+ @retval 0 The segment is broken.
+ @retval 1 The segment is in good shape.
+
**/
-VOID
+INTN
TcpTrimInWnd (
IN TCP_CB *Tcb,
IN NET_BUF *Nbuf
)
{
- TcpTrimSegment (Nbuf, Tcb->RcvNxt, Tcb->RcvWl2 + Tcb->RcvWnd);
+ return TcpTrimSegment (Nbuf, Tcb->RcvNxt, Tcb->RcvWl2 + Tcb->RcvWnd);
}
/**
Process the data and FIN flag, and check whether to deliver
data to the socket layer.
@@ -419,11 +425,20 @@ TcpDeliverData (
while (Entry != &Tcb->RcvQue) {
Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
Seg = TCPSEG_NETBUF (Nbuf);
- ASSERT (TcpVerifySegment (Nbuf) != 0);
+ if (TcpVerifySegment (Nbuf) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpToSendData: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+ NetbufFree (Nbuf);
+ return -1;
+ }
+
ASSERT (Nbuf->Tcp == NULL);
if (TCP_SEQ_GT (Seg->Seq, Seq)) {
break;
}
@@ -559,12 +574,15 @@ TcpDeliverData (
Store the data into the reassemble queue.
@param[in, out] Tcb Pointer to the TCP_CB of this TCP instance.
@param[in] Nbuf Pointer to the buffer containing the data to be queued.
+ @retval 0 An error condition occurred.
+ @retval 1 No error occurred to queue data.
+
**/
-VOID
+INTN
TcpQueueData (
IN OUT TCP_CB *Tcb,
IN NET_BUF *Nbuf
)
{
@@ -586,11 +604,11 @@ TcpQueueData (
// no out-of-order segments are received.
//
if (IsListEmpty (Head)) {
InsertTailList (Head, &Nbuf->List);
- return;
+ return 1;
}
//
// Find the point to insert the buffer
//
@@ -613,16 +631,16 @@ TcpQueueData (
Node = NET_LIST_USER_STRUCT (Prev, NET_BUF, List);
if (TCP_SEQ_LT (Seg->Seq, TCPSEG_NETBUF (Node)->End)) {
if (TCP_SEQ_LEQ (Seg->End, TCPSEG_NETBUF (Node)->End)) {
-
- NetbufFree (Nbuf);
- return;
+ return 1;
}
- TcpTrimSegment (Nbuf, TCPSEG_NETBUF (Node)->End, Seg->End);
+ if (TcpTrimSegment (Nbuf, TCPSEG_NETBUF (Node)->End, Seg->End) == 0) {
+ return 0;
+ }
}
}
InsertHeadList (Prev, &Nbuf->List);
@@ -646,31 +664,38 @@ TcpQueueData (
if (TCP_SEQ_LT (TCPSEG_NETBUF (Node)->Seq, Seg->End)) {
if (TCP_SEQ_LEQ (TCPSEG_NETBUF (Node)->Seq, Seg->Seq)) {
RemoveEntryList (&Nbuf->List);
- NetbufFree (Nbuf);
- return;
+ return 1;
}
- TcpTrimSegment (Nbuf, Seg->Seq, TCPSEG_NETBUF (Node)->Seq);
+ if (TcpTrimSegment (Nbuf, Seg->Seq, TCPSEG_NETBUF (Node)->Seq) == 0) {
+ RemoveEntryList (&Nbuf->List);
+ return 0;
+ }
break;
}
Cur = Cur->ForwardLink;
}
+
+ return 1;
}
/**
Adjust the send queue or the retransmit queue.
@param[in] Tcb Pointer to the TCP_CB of this TCP instance.
@param[in] Ack The acknowledge seuqence number of the received segment.
+ @retval 0 An error condition occurred.
+ @retval 1 No error occurred.
+
**/
-VOID
+INTN
TcpAdjustSndQue (
IN TCP_CB *Tcb,
IN TCP_SEQNO Ack
)
{
@@ -699,13 +724,14 @@ TcpAdjustSndQue (
RemoveEntryList (&Node->List);
NetbufFree (Node);
continue;
}
- TcpTrimSegment (Node, Ack, Seg->End);
- break;
+ return TcpTrimSegment (Node, Ack, Seg->End);
}
+
+ return 1;
}
/**
Process the received TCP segments.
@@ -891,11 +917,19 @@ TcpInput (
TcpInitTcbLocal (Tcb);
TcpInitTcbPeer (Tcb, Seg, &Option);
TcpSetState (Tcb, TCP_SYN_RCVD);
TcpSetTimer (Tcb, TCP_TIMER_CONNECT, Tcb->ConnectTimeout);
- TcpTrimInWnd (Tcb, Nbuf);
+ if (TcpTrimInWnd (Tcb, Nbuf) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpInput: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+
+ goto DISCARD;
+ }
goto StepSix;
}
goto DISCARD;
@@ -973,11 +1007,19 @@ TcpInput (
TcpComputeRtt (Tcb, Tcb->RttMeasure);
TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_RTT_ON);
}
- TcpTrimInWnd (Tcb, Nbuf);
+ if (TcpTrimInWnd (Tcb, Nbuf) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpInput: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+
+ goto DISCARD;
+ }
TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_ACK_NOW);
DEBUG (
(EFI_D_NET,
@@ -991,13 +1033,20 @@ TcpInput (
// Received a SYN segment without ACK, simultanous open.
//
TcpSetState (Tcb, TCP_SYN_RCVD);
ASSERT (Tcb->SndNxt == Tcb->Iss + 1);
- TcpAdjustSndQue (Tcb, Tcb->SndNxt);
- TcpTrimInWnd (Tcb, Nbuf);
+ if (TcpAdjustSndQue (Tcb, Tcb->SndNxt) == 0 || TcpTrimInWnd (Tcb, Nbuf) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpInput: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+
+ goto DISCARD;
+ }
DEBUG (
(EFI_D_WARN,
"TcpInput: simultaneous open for TCB %p in SYN_SENT\n",
Tcb)
@@ -1079,11 +1128,19 @@ TcpInput (
}
//
// Trim the data and flags.
//
- TcpTrimInWnd (Tcb, Nbuf);
+ if (TcpTrimInWnd (Tcb, Nbuf) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpInput: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+
+ goto DISCARD;
+ }
//
// Third step: Check security and precedence, Ignored
//
@@ -1254,11 +1311,20 @@ TcpInput (
TcpFastRecover (Tcb, Seg);
}
if (TCP_SEQ_GT (Seg->Ack, Tcb->SndUna)) {
- TcpAdjustSndQue (Tcb, Seg->Ack);
+ if (TcpAdjustSndQue (Tcb, Seg->Ack) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpInput: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+
+ goto DISCARD;
+ }
+
Tcb->SndUna = Seg->Ack;
if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_SND_URG) &&
TCP_SEQ_LT (Tcb->SndUp, Seg->Ack))
{
@@ -1487,11 +1553,20 @@ StepSix:
);
goto RESET_THEN_DROP;
}
- TcpQueueData (Tcb, Nbuf);
+ if (TcpQueueData (Tcb, Nbuf) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpInput: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+
+ goto DISCARD;
+ }
+
if (TcpDeliverData (Tcb) == -1) {
goto RESET_THEN_DROP;
}
if (!IsListEmpty (&Tcb->RcvQue)) {
diff --git a/NetworkPkg/TcpDxe/TcpOutput.c b/NetworkPkg/TcpDxe/TcpOutput.c index a7e59f0..1697514 100644
--- a/NetworkPkg/TcpDxe/TcpOutput.c
+++ b/NetworkPkg/TcpDxe/TcpOutput.c
@@ -290,11 +290,15 @@ TcpTransmitSegment (
TCP_HEAD *Head;
TCP_SEG *Seg;
BOOLEAN Syn;
UINT32 DataLen;
- ASSERT ((Nbuf != NULL) && (Nbuf->Tcp == NULL) && (TcpVerifySegment (Nbuf) != 0));
+ ASSERT ((Nbuf != NULL) && (Nbuf->Tcp == NULL));
+
+ if (TcpVerifySegment (Nbuf) == 0) {
+ return -1;
+ }
DataLen = Nbuf->TotalSize;
Seg = TCPSEG_NETBUF (Nbuf);
Syn = TCP_FLG_ON (Seg->Flag, TCP_FLG_SYN);
@@ -632,11 +636,15 @@ TcpGetSegment (
} else {
Nbuf = TcpGetSegmentSock (Tcb, Seq, Len);
}
- ASSERT (TcpVerifySegment (Nbuf) != 0);
+ if (TcpVerifySegment (Nbuf) == 0) {
+ NetbufFree (Nbuf);
+ return NULL;
+ }
+
return Nbuf;
}
/**
Retransmit the segment from sequence Seq.
@@ -699,11 +707,13 @@ TcpRetransmit (
Nbuf = TcpGetSegmentSndQue (Tcb, Seq, Len);
if (Nbuf == NULL) {
return -1;
}
- ASSERT (TcpVerifySegment (Nbuf) != 0);
+ if (TcpVerifySegment (Nbuf) == 0) {
+ goto OnError;
+ }
if (TcpTransmitSegment (Tcb, Nbuf) != 0) {
goto OnError;
}
@@ -884,12 +894,18 @@ TcpToSendData (
Seg->Seq = Seq;
Seg->End = End;
Seg->Flag = Flag;
- ASSERT (TcpVerifySegment (Nbuf) != 0);
- ASSERT (TcpCheckSndQue (&Tcb->SndQue) != 0);
+ if (TcpVerifySegment (Nbuf) == 0 || TcpCheckSndQue (&Tcb->SndQue) == 0) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "TcpToSendData: discard a broken segment for TCB %p\n",
+ Tcb)
+ );
+ goto OnError;
+ }
//
// Don't send an empty segment here.
//
if (Seg->End == Seg->Seq) {
@@ -897,12 +913,11 @@ TcpToSendData (
(EFI_D_WARN,
"TcpToSendData: created a empty segment for TCB %p, free it now\n",
Tcb)
);
- NetbufFree (Nbuf);
- return Sent;
+ goto OnError;
}
if (TcpTransmitSegment (Tcb, Nbuf) != 0) {
NetbufTrim (Nbuf, (Nbuf->Tcp->HeadLen << 2), NET_BUF_HEAD);
Nbuf->Tcp = NULL;
--
1.9.5.msysgit.1
prev parent reply other threads:[~2017-12-27 3:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-26 6:50 [Patch 3/3] NetworkPkg/TcpDxe: Check TCP payload for release version Jiaxin Wu
2017-12-27 3:03 ` Fu, Siyuan
2017-12-27 8:25 ` Wu, Jiaxin
2017-12-27 3:11 ` Ye, Ting [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=BC0C045B0E2A584CA4575E779FA2C12A1A987DE0@SHSMSX103.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox