Repository : ssh://git@open-mesh.org/batctl
On branch : next
commit 79f3061aa239f1bc8b50a62f403ab5e4dd0069d3 Author: Sven Eckelmann sven@narfation.org Date: Wed Nov 12 18:58:27 2014 +0100
batctl: Only parse TVLV data when length is valid
The length in a TVLV field must be smaller or equal to the length of the remaining read data. Otherwise the parser can read outside of the valid data region.
This regression was introduced by 4c39fb823b86036df40187f8bd342fe5398c28ef ("batctl: tcpdump - parse TVLV containers").
Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Marek Lindner mareklindner@neomailbox.ch
79f3061aa239f1bc8b50a62f403ab5e4dd0069d3 tcpdump.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/tcpdump.c b/tcpdump.c index 3e57544..443f671 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -258,15 +258,21 @@ static void dump_batman_ucast_tvlv(unsigned char *packet_buff, ssize_t buff_len,
while (tvlv_len >= (ssize_t)sizeof(*tvlv_hdr)) { tvlv_hdr = (struct batadv_tvlv_hdr *)ptr; + + /* data after TVLV header */ + ptr = (uint8_t *)(tvlv_hdr + 1); + tvlv_len -= sizeof(*tvlv_hdr); + len = ntohs(tvlv_hdr->len); + LEN_CHECK(tvlv_len, (size_t)len, "BAT UCAST TVLV");
parser = tvlv_parser_get(tvlv_hdr->type, tvlv_hdr->version); if (parser) - parser(tvlv_hdr + 1, len); + parser(ptr, len);
/* go to the next container */ - ptr = (uint8_t *)(tvlv_hdr + 1) + len; - tvlv_len -= sizeof(*tvlv_hdr) + len; + ptr += len; + tvlv_len -= len; } }
@@ -687,15 +693,21 @@ static void dump_batman_iv_ogm(unsigned char *packet_buff, ssize_t buff_len, int
while (tvlv_len >= (ssize_t)sizeof(*tvlv_hdr)) { tvlv_hdr = (struct batadv_tvlv_hdr *)ptr; + + /* data after TVLV header */ + ptr = (uint8_t *)(tvlv_hdr + 1); + tvlv_len -= sizeof(*tvlv_hdr); + len = ntohs(tvlv_hdr->len); + LEN_CHECK(tvlv_len, (size_t)len, "BAT IV OGM TVLV");
parser = tvlv_parser_get(tvlv_hdr->type, tvlv_hdr->version); if (parser) - parser(tvlv_hdr + 1, len); + parser(ptr, len);
/* go to the next container */ - ptr = (uint8_t *)(tvlv_hdr + 1) + len; - tvlv_len -= sizeof(*tvlv_hdr) + len; + ptr += len; + tvlv_len -= len; } }