Now all the macros have a name meaning a count in bytes.
With _S_: signed, _U_: unsigned
e.g.:
EXTRACT_BE_32BITS -> EXTRACT_BE_U_4
EXTRACT_LE_32BITS -> EXTRACT_LE_U_4
...
EXTRACT_BE_INT32 -> EXTRACT_BE_S_4
and have:
EXTRACT_8BITS -> EXTRACT_U_1
EXTRACT_INT8 -> EXTRACT_S_1
dhcpv4_print() in print-hncp.c had the same bug as dhcpv6_print(), apply
a fix along the same lines.
This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.
Add a test using the capture file supplied by the reporter(s).
hncp_print_rec() validates each HNCP TLV to be within the declared as
well as the on-the-wire packet space. However, dhcpv6_print() in the same
file didn't do the same for the DHCPv6 options within the HNCP
DHCPv6-Data TLV value, which could cause an out-of-bounds read when
decoding an invalid packet. Add missing checks to dhcpv6_print().
This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.
Add a test using the capture file supplied by the reporter(s).
This squelches a warning in format_256(), make a similar change to
format_nid() while at it.
$ gcc --version
gcc (GCC) 7.1.1 20170622 (Red Hat 7.1.1-3)
./print-hncp.c: In function ‘format_256’:
./print-hncp.c:175:26: warning: ‘%016lx’ directive output truncated writing 16 bytes into a region of size 12 [-Wformat-truncation=]
snprintf(buf[i], 28, "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
^~~~~~
./print-hncp.c:175:41: note: format string is defined here
snprintf(buf[i], 28, "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
./print-hncp.c:175:26: note: using the range [0, 18446744073709551615] for directive argument
snprintf(buf[i], 28, "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
^~~~~~
./print-hncp.c:175:26: note: using the range [0, 18446744073709551615] for directive argument
./print-hncp.c:175:26: note: using the range [0, 18446744073709551615] for directive argument
./print-hncp.c:175:5: note: ‘snprintf’ output 65 bytes into a destination of size 28
snprintf(buf[i], 28, "%016" PRIx64 "%016" PRIx64 "%016" PRIx64 "%016" PRIx64,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EXTRACT_64BITS(data),
~~~~~~~~~~~~~~~~~~~~~
EXTRACT_64BITS(data + 8),
~~~~~~~~~~~~~~~~~~~~~~~~~
EXTRACT_64BITS(data + 16),
~~~~~~~~~~~~~~~~~~~~~~~~~~
EXTRACT_64BITS(data + 24)
~~~~~~~~~~~~~~~~~~~~~~~~~
);
~
Have a routine to check for those addresses, and use it in all cases.
Have a #define for the length of the fixed part of those addresses at
the beginning, and use it.
Fix a length check; Coverity noted that the check never failed, because
we were comparing the length of the prefix field in the packet with the
length of the IPv4 prefix, not the length of the IPv4 prefix plus the
fixed part at the beginning.
Do *NOT* just use decode_prefix4(); it assumes that the data is in the
packet buffer, and does ND_TCHECK() on it, which is not guaranteed to
work if it's *not* in the packet buffer. Instead, do something similar
to what decode_prefix4() does, but on an HNCP-style prefix. Also, when
calling decode_prefix6(), pass it the actual size of the buffer we fill
in.
That buffer, BTW, does not need to be static, so it shouldn't be static.
Make sure we check *all* of the first 12 bytes of the prefix; just use
one memcmp call to check for 10 bytes of 0 followed by 2 bytes of 0xFF.
Don't use safeputs() on the formatted string for the prefix; it's
guaranteed 1) not to have any strange characters and 2) to be
null-terminated.
For invalid body lengths for a TLV, just report a error for that TLV,
but keep processing TLVs.
Handle "the prefix length is invalid" and "the prefix runs past the end
of the packet" differently.