From: Martin Schwenke Date: Fri, 17 Aug 2018 11:26:04 +0000 (+1000) Subject: ctdb-common: Improve TCP packet size and offset calculations X-Git-Tag: tdb-1.3.17~1960 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=924a655b2a56edea66064dd1fdf67d9b7e093b64;p=thirdparty%2Fsamba.git ctdb-common: Improve TCP packet size and offset calculations The IPv4 check for short packets was strange. It appeared to ensure that the capture included everything up to and including the window size. The checksum field immediately follows the window size field, so just ensure that the packet is large enough to contain everything up to the start of the checksum. Add a similar check for IPv6 packets. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/common/system_socket.c b/ctdb/common/system_socket.c index 8de70f8bca6..99c83c0ed5a 100644 --- a/ctdb/common/system_socket.c +++ b/ctdb/common/system_socket.c @@ -768,13 +768,14 @@ static int tcp4_extract(const uint8_t *ip_pkt, return ENOMSG; } - /* make sure its not a short packet */ - if (offsetof(struct tcphdr, th_ack) + 4 + (ip->ip_hl*4) > pktlen) { + /* Ensure there is enough of the packet to gather required fields */ + if (pktlen < + (ip->ip_hl * sizeof(uint32_t)) + offsetof(struct tcphdr, th_sum)) { return EMSGSIZE; } /* TCP */ - tcp = (const struct tcphdr *)((ip->ip_hl*4) + (const char *)ip); + tcp = (const struct tcphdr *)(ip_pkt + (ip->ip_hl * sizeof(uint32_t))); /* tell the caller which one we've found */ src->sin_family = AF_INET; @@ -809,7 +810,8 @@ static int tcp6_extract(const uint8_t *ip_pkt, const struct ip6_hdr *ip6; const struct tcphdr *tcp; - if (pktlen < sizeof(struct ip6_hdr)) { + /* Ensure there is enough of the packet to gather required fields */ + if (pktlen < sizeof(struct ip6_hdr) + offsetof(struct tcphdr, th_sum)) { return EMSGSIZE; } @@ -822,7 +824,7 @@ static int tcp6_extract(const uint8_t *ip_pkt, } /* TCP */ - tcp = (const struct tcphdr *)(ip6+1); + tcp = (const struct tcphdr *)(ip_pkt + sizeof(struct ip6_hdr)); /* tell the caller which one we've found */ src->sin6_family = AF_INET6;