ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000512c08 at pc 0x00000041848d bp 0x7ffcdde71870 sp 0x7ffcdde71860
READ of size 8 at 0x000000512c08 thread T0
#0 0x41848c in print_attributes monitor/nlmon.c:6268
#1 0x42ac53 in print_message monitor/nlmon.c:6544
#2 0x438968 in nlmon_message monitor/nlmon.c:6698
#3 0x43d5e4 in nlmon_receive monitor/nlmon.c:7658
#4 0x4b3cd0 in io_callback ell/io.c:120
#5 0x4b085a in l_main_iterate ell/main.c:478
#6 0x4b0ee3 in l_main_run ell/main.c:525
#7 0x4b0ee3 in l_main_run ell/main.c:507
#8 0x4b13ac in l_main_run_with_signal ell/main.c:647
#9 0x4072fe in main monitor/main.c:811
To help understand scanning results a bit better and cut down on scan
output add an option to not print the contents of the IEs. Only the
SSID IE will be printed.
NLMSG_OK and NLMSG_NEXT expect to operate on nlmsg_len which is an int
(signed type). The current code uses an unsigned type which means that
it cannot detect underflows. Such underflows can happen when NLMSG_NEXT
tries to advance nlmsg_len by a number of bytes (due to alignment) which
are greater than the current nlmsg_len itself. This causes iwmon to
crash on certain messages.
Reported-By: Daniel Wagner <wagi@monom.org>
This dumper probably intended to update pos after invoking strncpy.
However, strncpy returns the number of bytes that *would* have been
copied and so the logic gets a bit complex to get completely right.
Instead, switch to using l_string since this is inside the monitor and
not particularly performance critical.
Simply prints the ANQP ID (human readable) and the length. Once
the ANQP dependency on netdev is removed the full ANQP parser
can be used, but for now its done manually. Once this is done it
will be much easier to print the actual ANQP ID data.
Inside print_ie_vendor, the Microsoft OUI is checked for a WPA IE. The
variable name for the OUI was wfa_oui, but this OUI is not actually the
WiFi-Alliance (sometimes refered to as 'wfa') but rather the Microsoft
OUI.
Added handling for several FILS IEs and NL attributes specific to
FILS. Also changed "SAE Data" to "Auth Data" since its now used for
both SAE and FILS.
Unfortunately there is no way to determine the MIC length just from the
eapol frame. 802.11 defined AKMs define the MIC length, but non 802.11
AKMs (e.g. OWE) can define their own MIC length. For this reason it seem
infeasable to track these special AKM's data flow to determine the MIC
length.
To work around this we can just try different MIC lengths (since there
are only 3 after all). This allows us to get key data length and see if
the total packet size equals the frame length + key data length. If the
sizes don't match we can try the next MIC length.
The MIC length was hard coded to 16 bytes everywhere, and since several
AKMs require larger MIC's (24/32) this needed to change. The main issue
was that the MIC was hard coded to 16 bytes inside eapol_key. Instead
of doing this, the MIC, key_data_length, and key_data elements were all
bundled into key_data[0]. In order to retrieve the MIC, key_data_len,
or key_data several macros were introduced which account for the MIC
length provided.
A consequence of this is that all the verify functions inside eapol now
require the MIC length as a parameter because without it they cannot
determine the byte offset of key_data or key_data_length.
The MIC length for a given handshake is set inside the SM when starting
EAPoL. This length is determined by the AKM for the handshake.
Fixes:
CC monitor/pcap.o
monitor/pcap.c: In function ‘pcap_create’:
monitor/pcap.c:121:6: error: ‘S_IRUSR’ undeclared (first use in this function)
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
^
monitor/pcap.c:121:6: note: each undeclared identifier is reported only once for each function it appears in
monitor/pcap.c:121:16: error: ‘S_IWUSR’ undeclared (first use in this function)
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
^
monitor/pcap.c:121:26: error: ‘S_IRGRP’ undeclared (first use in this function)
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
^
monitor/pcap.c:121:36: error: ‘S_IROTH’ undeclared (first use in this function)
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
^
==24195== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==24195== at 0x4F3DBEF: sendto (in /lib64/libc-2.26.so)
==24195== by 0x13A453: can_write_data (netlink.c:119)
==24195== by 0x13866B: io_callback (io.c:149)
==24195== by 0x137365: l_main_iterate (main.c:389)
==24195== by 0x1374A3: l_main_run (main.c:436)
==24195== by 0x113524: main (main.c:832)
==24195== Address 0x5205f99 is 57 bytes inside a block of size 88 alloc'd
==24195== at 0x4C2D0AF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24195== by 0x133931: l_malloc (util.c:62)
==24195== by 0x13AEF3: l_netlink_send (netlink.c:411)
==24195== by 0x112351: rtm_interface_send_message (main.c:276)
==24195== by 0x1126F3: iwmon_interface_lookup (main.c:405)
==24195== by 0x11351F: main (main.c:830)
==24195== Uninitialised value was created by a heap allocation
==24195== at 0x4C2D0AF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24195== by 0x133931: l_malloc (util.c:62)
==24195== by 0x11217B: rtm_interface_send_message (main.c:234)
==24195== by 0x1126F3: iwmon_interface_lookup (main.c:405)
==24195== by 0x11351F: main (main.c:830)
==23290== Invalid read of size 4
==23290== at 0x12D334: timeout_destroy (timeout.c:61)
==23290== by 0x12CDD1: l_main_exit (main.c:466)
==23290== by 0x111F3B: main (main.c:835)
==23290== Address 0x5211d80 is 0 bytes inside a block of size 32 free'd
==23290== at 0x4C2E1BB: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23290== by 0x111F36: main (main.c:833)
==23290== Block was alloc'd at
==23290== at 0x4C2CF8F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23290== by 0x12A74D: l_malloc (util.c:62)
==23290== by 0x12D40F: timeout_create_with_nanoseconds (timeout.c:135)
==23290== by 0x112A31: signal_handler (main.c:661)
==23290== by 0x12D03A: signal_callback (signal.c:82)
==23290== by 0x12CC6D: l_main_iterate (main.c:387)
==23290== by 0x12CD3B: l_main_run (main.c:434)
==23290== by 0x1121F2: main (main.c:821)
==23290==
==23290== Invalid read of size 8
==23290== at 0x12D33B: timeout_destroy (timeout.c:64)
==23290== by 0x12CDD1: l_main_exit (main.c:466)
==23290== by 0x111F3B: main (main.c:835)
==23290== Address 0x5211d90 is 16 bytes inside a block of size 32 free'd
==23290== at 0x4C2E1BB: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23290== by 0x111F36: main (main.c:833)
==23290== Block was alloc'd at
==23290== at 0x4C2CF8F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23290== by 0x12A74D: l_malloc (util.c:62)
==23290== by 0x12D40F: timeout_create_with_nanoseconds (timeout.c:135)
==23290== by 0x112A31: signal_handler (main.c:661)
==23290== by 0x12D03A: signal_callback (signal.c:82)
==23290== by 0x12CC6D: l_main_iterate (main.c:387)
==23290== by 0x12CD3B: l_main_run (main.c:434)
==23290== by 0x1121F2: main (main.c:821)
==23290==
==23290== Invalid write of size 4
==23290== at 0x12D33F: timeout_destroy (timeout.c:62)
==23290== by 0x12CDD1: l_main_exit (main.c:466)
==23290== by 0x111F3B: main (main.c:835)
==23290== Address 0x5211d80 is 0 bytes inside a block of size 32 free'd
==23290== at 0x4C2E1BB: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23290== by 0x111F36: main (main.c:833)
==23290== Block was alloc'd at
==23290== at 0x4C2CF8F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==23290== by 0x12A74D: l_malloc (util.c:62)
==23290== by 0x12D40F: timeout_create_with_nanoseconds (timeout.c:135)
==23290== by 0x112A31: signal_handler (main.c:661)
==23290== by 0x12D03A: signal_callback (signal.c:82)
==23290== by 0x12CC6D: l_main_iterate (main.c:387)
==23290== by 0x12CD3B: l_main_run (main.c:434)
==23290== by 0x1121F2: main (main.c:821)
to fix compilation against MUSL libc.
The struct ethhdr does exists in netinet/if_ether.h and linux/if_ether.h
so including the linux headers after the libc headers lets libc_compat.h
work as intended.