[PATCH 14/28] batctl: tcpdump: handle TCP packet with bogus data offset
Sven Eckelmann <[email protected]> Sun, 21 Jun 2026 16:24:04 +0200
| Newsgroups | org.open-mesh.lists.batman |
|---|---|
| Message-ID | <[email protected]> |
dump_tcp() computes length as (buff_len - ip6_header_len - tcp_header_len),
but the only bounds guard ensures 20 bytes, while doff allows a higher
header length (60 bytes). With a doff of 15 (60 bytes) and only 20 bytes
available in the buffer, the calculation would underflow and show a bugus
length of the TCP payload. For now, set the payload length to zero for such
a packet.
Fixes: 35b37756f4a3 ("add IPv6 support to tcpdump parser")
Signed-off-by: Sven Eckelmann <[email protected]>
---
tcpdump.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tcpdump.c b/tcpdump.c
index 9c90f36..7769cbf 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -537,18 +537,20 @@ static void dump_tcp(const char ip_string[], unsigned char *packet_buff,
{
uint16_t tcp_header_len;
struct tcphdr *tcphdr;
+ size_t tcp_len;
LEN_CHECK((size_t)buff_len - ip6_header_len,
sizeof(struct tcphdr), "TCP");
tcphdr = (struct tcphdr *)(packet_buff + ip6_header_len);
tcp_header_len = tcphdr->doff * 4;
+ tcp_len = (size_t)buff_len - ip6_header_len;
printf("%s %s.%i > ", ip_string, src_addr, ntohs(tcphdr->source));
printf("%s.%i: TCP, Flags [%c%c%c%c%c%c], length %zu\n",
dst_addr, ntohs(tcphdr->dest),
(tcphdr->fin ? 'F' : '.'), (tcphdr->syn ? 'S' : '.'),
(tcphdr->rst ? 'R' : '.'), (tcphdr->psh ? 'P' : '.'),
(tcphdr->ack ? 'A' : '.'), (tcphdr->urg ? 'U' : '.'),
- (size_t)buff_len - ip6_header_len - tcp_header_len);
+ tcp_len > tcp_header_len ? tcp_len - tcp_header_len : 0);
}
static void dump_udp(const char ip_string[], unsigned char *packet_buff,
--
2.47.3