From 710fbb81a53758bbedd7861b18c2a075f7ae9935 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 7 Aug 2026 07:41:23 +0000 Subject: [PATCH] pcap/log: expand buffer before write in PcapLogSegmentCallback Segment logging could create larger buffers than the thread buffer available, which would be silently truncated. However the length passed to libpcap was still of the non-truncated size, so this would lead libpcap to read past the end of the buffer. Fix by trying to expand the buffer as needed. Ticket: #8835. --- src/log-pcap.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/log-pcap.c b/src/log-pcap.c index 1468cd1447..61fb76d7cc 100644 --- a/src/log-pcap.c +++ b/src/log-pcap.c @@ -574,14 +574,32 @@ static int PcapLogSegmentCallback( SCTIME_TO_TIMEVAL(&tv, seg->pcap_hdr_storage->ts); pctx->td->pcap_log->h->ts.tv_sec = tv.tv_sec; pctx->td->pcap_log->h->ts.tv_usec = tv.tv_usec; - pctx->td->pcap_log->h->len = seg->pcap_hdr_storage->pktlen + buflen; - pctx->td->pcap_log->h->caplen = seg->pcap_hdr_storage->pktlen + buflen; + + /* Ensure the buffer can hold the full packet: headers + payload. + */ + const uint32_t pktlen = seg->pcap_hdr_storage->pktlen; + const uint32_t total_len = pktlen + buflen; + + if (unlikely(total_len >= MEMBUFFER_SIZE(pctx->td->buf))) { + uint32_t expand_by = total_len + 1 - MEMBUFFER_SIZE(pctx->td->buf); + if (expand_by % 4096 != 0) { + expand_by = expand_by - (expand_by % 4096) + 4096; + } + if (unlikely(MemBufferExpand(&pctx->td->buf, expand_by) < 0)) { + SCLogWarning("Failed to expand pcap-log buffer for segment " + "of size %u", + total_len); + return 1; + } + } + + pctx->td->pcap_log->h->len = total_len; + pctx->td->pcap_log->h->caplen = total_len; MemBufferReset(pctx->td->buf); - MemBufferWriteRaw( - pctx->td->buf, seg->pcap_hdr_storage->pkt_hdr, seg->pcap_hdr_storage->pktlen); + MemBufferWriteRaw(pctx->td->buf, seg->pcap_hdr_storage->pkt_hdr, pktlen); MemBufferWriteRaw(pctx->td->buf, buf, buflen); - PcapWrite(pctx->tv, pctx->td, (uint8_t *)pctx->td->buf->buffer, pctx->td->pcap_log->h->len); + PcapWrite(pctx->tv, pctx->td, (uint8_t *)pctx->td->buf->buffer, total_len); } return 1; }