batctl: tcpdump - parse TVLV containers
PATCH v5 1/1 batctl: tcpdump - parse TVLV containers
From: Antonio Quartulli <[email protected]>
OGMs and unicast TVLV packets carry TVLV containers as payload.
With this patch such containers are now parsed and the relevant information is printed to screen.
---
changes since v4:
- avoid warning in LEN_CHECK macro
changes since v3:
- undo unneeded style change in tcpdump.c
- remove unneeded sentence about style change sin commit message
changes since v2:
- extended doc in README and manpage
changes since v1:
- remove all the style changes
- make tvlv_len of type ssize_t in dump_batman_iv_ogm()
README | 1 + main.h | 7 +++ man/batctl.8 | 3 ++ tcpdump.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- tcpdump.h | 1 + 5 files changed, 177 insertions(+), 4 deletions(-)
README +1 -0
@@ -161,6 +161,7 @@ packet types: 2 - batman icmp packets 4 - batman unicast packets 8 - batman broadcast packets + 16 - batman unicast tvlv packets 32 - batman fragmented packets 64 - batman tt / roaming packets 128 - non batman packets
main.h +7 -0
@@ -49,4 +49,11 @@extern char module_ver_path[]; +#ifndef VLAN_VID_MASK +#define VLAN_VID_MASK 0xfff +#endif + +#define BATADV_PRINT_VID (vid) (vid & BATADV_VLAN_HAS_TAG ? \ + (int)(vid & VLAN_VID_MASK) : -1) +#endif
man/batctl.8 +3 -0
@@ -288,6 +288,9 @@ except specified). The following packet types are available: 8 - batman broadcast packets .RE .RS 16 +16 - batman unicast tvlv packets +.RE +.RS 16 32 - batman fragmented packets .RE .RS 16
tcpdump.c +165 -4
212 lines not on this page · raw message
tcpdump.h +1 -0
@@ -41,6 +41,7 @@#define DUMP_TYPE_BATICMP 2#define DUMP_TYPE_BATUCAST 4#define DUMP_TYPE_BATBCAST 8 +#define DUMP_TYPE_BATUTVLV 16#define DUMP_TYPE_BATFRAG 32#define DUMP_TYPE_NONBAT 128
Signature · 1 line
2.1.3
Marek Lindner
AppliedQuoted 8 lines · On Sunday 02 November 2014 09:38:04 Antonio Quartulli wrote:
From: Antonio Quartulli <[email protected]>
OGMs and unicast TVLV packets carry TVLV containers as payload.
With this patch such containers are now parsed and the relevant information is printed to screen.Signed-off-by Antonio Quartulli <[email protected]>
Applied in revision 4c39fb8.
Thanks,
Marek
Quoted 12 lines
tcpdump.c +12
-0+typedef void (*batctl_tvlv_parser_t )(void *buff,ssize_t buff_len); + +/* location [i][j] contains the parsing function for TVLV of type 'i' and +* version 'j + 1' +*/ +batctl_tvlv_parser_t tvlv_parsers[][1 ] = { + [BATADV_TVLV_GW ][0 ] = batctl_tvlv_parse_gw_v1, + [BATADV_TVLV_DAT ][0 ] = batctl_tvlv_parse_dat_v1, + [BATADV_TVLV_NC ][0 ] = batctl_tvlv_parse_nc_v1, + [BATADV_TVLV_TT ][0 ] = batctl_tvlv_parse_tt_v1, + [BATADV_TVLV_ROAM ][0 ] = batctl_tvlv_parse_roam_v1, +};
[....]
Quoted 13 lines
tcpdump.c +13
-0+while (tvlv_len >0 ) { + tvlv_hdr = (struct batadv_tvlv_hdr *)ptr; + len =ntohs (tvlv_hdr->len); + + parser = tvlv_parsers[tvlv_hdr->type][tvlv_hdr->version -1 ]; +parser (tvlv_hdr +1 , len); + +/* go to the next container */ + ptr = (uint8_t *)(tvlv_hdr +1 ) + len; + tvlv_len -=sizeof (*tvlv_hdr) + len; + } +} +
[....]
tcpdump.c static void dump_batman_iv_ogm(unsigned char *packet_buff, ssize_t buff_len, int · line 661
Quoted 12 lines
tcpdump.c +11
-0+while (tvlv_len >0 ) { + tvlv_hdr = (struct batadv_tvlv_hdr *)ptr; + len =ntohs (tvlv_hdr->len); + + parser = tvlv_parsers[tvlv_hdr->type][tvlv_hdr->version -1 ]; +parser (tvlv_hdr +1 , len); + +/* go to the next container */ + ptr = (uint8_t *)(tvlv_hdr +1 ) + len; + tvlv_len -=sizeof (*tvlv_hdr) + len; + } }
I've already explained this to Antonio but here again in public:
* neither type nor version are validated
* the type can point in tvlv_parsers to an invalid (non-existing) entry
* the version of this entry can also point to an invalid parser
* this is a big problem because I can crash batctl td with data packets send from other people (even valid data packets with mcast tvlv)
* I've already experienced this problem when using nodes from a company which ships this patch since a while (> 4 months)
Maybe it can be redone with some switch statements or
(more space consuming) full tables which can handle all input data. Of course a check of the returned parser is still necessary inside the loops.
Kind regards,
Sven
On Tuesday 11 November 2014 23:56:03 Sven Eckelmann wrote:
[...]
Quoted 10 lines
I've already explained this to Antonio but here again in public:
* neither type nor version are validated
* the type can point intvlv_parsersto an invalid (non-existing) entry
* the version of this entry can also point to an invalid parser
* this is a big problem because I can crash batctl td with data packets send from other people (even valid data packets with mcast tvlv)
* I've already experienced this problem when using nodes from a company which ships this patch since a while (> 4 months)
Quoted 6 lines
Maybe it can be redone with some switch statements or
(more space consuming) full tables which can handle all input data. Of course a check of the returned parser is still necessary inside the loops.Kind regards,
Sven
For people who require a direct experience of the crash with normal traffic send by batman-adv:
1. compile batctl:
CFLAGS="-g3 -fsanitize=address -fsanitize=undefined -fsanitize=leak" make
2. Start it on some interfaceL
sudo ./batctl td eth0
3. run on another console tcpreplay on the same interface:
sudo tcpreplay -i eth0 v15_iv_ogm.pcapng
4. experience the crash:
10:17:28.724487 BAT 00:21:cc:b4:82:33: OGM IV via neigh 00:21:cc:b4:82:33, seq 3093200194, tq 255, ttl 50, v 15, flags [..F], length 68, tvlv_len 44
TVLV TTv1: OGM DIFF [.] ttvn=4 vlan_num=1 entry_num=0
VLAN ID -1, crc 0xb8d4beb4
TVLV GWv1: down 10.0Mbps, up 2.0Mbps
=================================================================
==4213==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000639410 at pc 0x415f75 bp 0x7ffff4a02c70 sp 0x7ffff4a02c68
READ of size 8 at 0x000000639410 thread T0
#0 0x415f74 in dump_batman_iv_ogm batctl/tcpdump.c:654
#1 0x41710e in parse_eth_hdr batctl/tcpdump.c:825
#2 0x4195c8 in tcpdump batctl/tcpdump.c:1118
#3 0x403b7a in main batctl/main.c:146
#4 0x7fd0f52dbb44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
#5 0x4029d8 (batctl+0x4029d8)0x000000639410 is located 0 bytes to the right of global variable 'tvlv_parsers' from 'tcpdump.c' (0x6393e0) of size 48 0x000000639410 is located 48 bytes to the left of global variable '*.Lubsan_type7' from 'tcpdump.c' (0x639440) of size 4
SUMMARY: AddressSanitizer: global-buffer-overflow batctl/tcpdump.c:654 dump_batman_iv_ogm
Shadow bytes around the buggy address:
0x0000800bf230: 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 f9 f9 f9
0x0000800bf240: f9 f9 f9 f9 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9
0x0000800bf250: 00 00 00 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
0x0000800bf260: 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9
0x0000800bf270: 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
=>0x0000800bf280: 00 00[f9]f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
0x0000800bf290: 00 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9
0x0000800bf2a0: f9 f9 f9 f9 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9
0x0000800bf2b0: 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
0x0000800bf2c0: 00 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
0x0000800bf2d0: 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7
Contiguous container OOB:fc
ASan internal: fe
==4213==ABORTING
Kind regards,
Sven