From: Shivani Bhardwaj Date: Sat, 15 Mar 2025 09:40:39 +0000 (+0530) Subject: stream: add defensive checks and comments X-Git-Tag: suricata-8.0.0-beta1~211 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d096b989c813dcc71154a9080cadaee927e45d24;p=thirdparty%2Fsuricata.git stream: add defensive checks and comments --- diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 18d3dd2c8b..a1685d4d15 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -1099,6 +1099,8 @@ static void GetSessionSize(TcpSession *ssn, Packet *p) static inline bool GapAhead(const TcpStream *stream, StreamingBufferBlock *cur_blk) { StreamingBufferBlock *nblk = SBB_RB_NEXT(cur_blk); + /* only if the stream has been ack'd, consider a gap for sure + * otherwise there may still be a chance of pkts coming in */ if (nblk && (cur_blk->offset + cur_blk->len < nblk->offset) && GetAbsLastAck(stream) > (cur_blk->offset + cur_blk->len)) { return true; @@ -1419,8 +1421,10 @@ int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, if (ssn->state >= TCP_CLOSING || (p->flags & PKT_PSEUDO_STREAM_END)) { SCLogDebug("sending empty eof message"); /* send EOF to app layer */ - AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, &stream, NULL, 0, - StreamGetAppLayerFlags(ssn, stream, p), app_update_dir); + uint8_t stream_flags = StreamGetAppLayerFlags(ssn, stream, p); + DEBUG_VALIDATE_BUG_ON((stream_flags & STREAM_EOF) == 0); + AppLayerHandleTCPData( + tv, ra_ctx, p, p->flow, ssn, &stream, NULL, 0, stream_flags, app_update_dir); AppLayerProfilingStore(ra_ctx->app_tctx, p); SCReturnInt(0); @@ -1442,10 +1446,11 @@ static int GetRawBuffer(const TcpStream *stream, const uint8_t **data, uint32_t if (RB_EMPTY(&stream->sb.sbb_tree)) { SCLogDebug("getting one blob for offset %"PRIu64, offset); + /* No gaps in the stream, data must exist in the streaming buffer array */ uint64_t roffset = offset; - if (offset) + if (offset) { StreamingBufferGetDataAtOffset(&stream->sb, &mydata, &mydata_len, offset); - else { + } else { StreamingBufferGetData(&stream->sb, &mydata, &mydata_len, &roffset); } @@ -1703,8 +1708,12 @@ static int StreamReassembleRawInline(TcpSession *ssn, const Packet *p, mydata_len -= excess; SCLogDebug("cutting tail of the buffer with %u", excess); } else { - uint32_t before = (uint32_t)(packet_leftedge_abs - mydata_offset); - uint32_t after = (uint32_t)(mydata_rightedge_abs - packet_rightedge_abs); + DEBUG_VALIDATE_BUG_ON(mydata_offset > packet_leftedge_abs); + uint32_t abs_before = (uint32_t)(packet_leftedge_abs - mydata_offset); + DEBUG_VALIDATE_BUG_ON(packet_rightedge_abs > mydata_rightedge_abs); + uint32_t abs_after = (uint32_t)(mydata_rightedge_abs - packet_rightedge_abs); + uint32_t before = abs_before; + uint32_t after = abs_after; SCLogDebug("before %u after %u", before, after); if (after >= (chunk_size - p->payload_len) / 2) { @@ -1729,8 +1738,10 @@ static int StreamReassembleRawInline(TcpSession *ssn, const Packet *p, } /* adjust the buffer */ - uint32_t skip = (uint32_t)(packet_leftedge_abs - mydata_offset) - before; - uint32_t cut = (uint32_t)(mydata_rightedge_abs - packet_rightedge_abs) - after; + DEBUG_VALIDATE_BUG_ON(before > abs_before); + uint32_t skip = abs_before - before; + DEBUG_VALIDATE_BUG_ON(after > abs_after); + uint32_t cut = abs_after - after; DEBUG_VALIDATE_BUG_ON(skip > mydata_len); DEBUG_VALIDATE_BUG_ON(cut > mydata_len); DEBUG_VALIDATE_BUG_ON(skip + cut > mydata_len);