diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-10-10 14:52:54 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-10-10 15:03:56 +0200 |
commit | dd5bab0c095101fa92c56acd7e2707c545d315db (patch) | |
tree | 8f90392045d9e66512ae2dd4cde10de6414410e4 /lib/prefix.c | |
parent | bgpd: Ensure that struct prefix_rd rd is zero'ed out (diff) | |
download | frr-dd5bab0c095101fa92c56acd7e2707c545d315db.tar.xz frr-dd5bab0c095101fa92c56acd7e2707c545d315db.zip |
lib: Fix read beyond end of data structure
Our Address Sanitizer CI is finding this issue:
error 09-Oct-2019 19:28:33 r4: bgpd triggered an exception by AddressSanitizer
error 09-Oct-2019 19:28:33 ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffdd425b060 at pc 0x00000068575f bp 0x7ffdd4258550 sp 0x7ffdd4258540
error 09-Oct-2019 19:28:33 READ of size 1 at 0x7ffdd425b060 thread T0
error 09-Oct-2019 19:28:33 #0 0x68575e in prefix_cmp lib/prefix.c:776
error 09-Oct-2019 19:28:33 #1 0x5889f5 in rfapiItBiIndexSearch bgpd/rfapi/rfapi_import.c:2230
error 09-Oct-2019 19:28:33 #2 0x5889f5 in rfapiBgpInfoFilteredImportVPN bgpd/rfapi/rfapi_import.c:3520
error 09-Oct-2019 19:28:33 #3 0x58b909 in rfapiProcessWithdraw bgpd/rfapi/rfapi_import.c:4071
error 09-Oct-2019 19:28:33 #4 0x4c459b in bgp_withdraw bgpd/bgp_route.c:3736
error 09-Oct-2019 19:28:33 #5 0x484122 in bgp_nlri_parse_vpn bgpd/bgp_mplsvpn.c:237
error 09-Oct-2019 19:28:33 #6 0x497f52 in bgp_nlri_parse bgpd/bgp_packet.c:315
error 09-Oct-2019 19:28:33 #7 0x49d06d in bgp_update_receive bgpd/bgp_packet.c:1598
error 09-Oct-2019 19:28:33 #8 0x49d06d in bgp_process_packet bgpd/bgp_packet.c:2274
error 09-Oct-2019 19:28:33 #9 0x6b9f54 in thread_call lib/thread.c:1531
error 09-Oct-2019 19:28:33 #10 0x657037 in frr_run lib/libfrr.c:1052
error 09-Oct-2019 19:28:33 #11 0x42d268 in main bgpd/bgp_main.c:486
error 09-Oct-2019 19:28:33 #12 0x7f806032482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
error 09-Oct-2019 19:28:33 #13 0x42bcc8 in _start (/usr/lib/frr/bgpd+0x42bcc8)
error 09-Oct-2019 19:28:33
error 09-Oct-2019 19:28:33 Address 0x7ffdd425b060 is located in stack of thread T0 at offset 240 in frame
error 09-Oct-2019 19:28:33 #0 0x483945 in bgp_nlri_parse_vpn bgpd/bgp_mplsvpn.c:103
error 09-Oct-2019 19:28:33
error 09-Oct-2019 19:28:33 This frame has 5 object(s):
error 09-Oct-2019 19:28:33 [32, 36) 'label'
error 09-Oct-2019 19:28:33 [96, 108) 'rd_as'
error 09-Oct-2019 19:28:33 [160, 172) 'rd_ip'
error 09-Oct-2019 19:28:33 [224, 240) 'prd' <== Memory access at offset 240 overflows this variable
error 09-Oct-2019 19:28:33 [288, 336) 'p'
error 09-Oct-2019 19:28:33 HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
error 09-Oct-2019 19:28:33 (longjmp and C++ exceptions *are* supported)
error 09-Oct-2019 19:28:33 SUMMARY: AddressSanitizer: stack-buffer-overflow lib/prefix.c:776 prefix_cmp
error 09-Oct-2019 19:28:33 Shadow bytes around the buggy address:
error 09-Oct-2019 19:28:33 0x10003a8435b0: 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00 00 00
error 09-Oct-2019 19:28:33 0x10003a8435c0: 00 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 f3 f3
error 09-Oct-2019 19:28:33 0x10003a8435d0: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00
error 09-Oct-2019 19:28:33 0x10003a8435e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
error 09-Oct-2019 19:28:33 0x10003a8435f0: f1 f1 04 f4 f4 f4 f2 f2 f2 f2 00 04 f4 f4 f2 f2
error 09-Oct-2019 19:28:33 =>0x10003a843600: f2 f2 00 04 f4 f4 f2 f2 f2 f2 00 00[f4]f4 f2 f2
error 09-Oct-2019 19:28:33 0x10003a843610: f2 f2 00 00 00 00 00 00 f4 f4 f3 f3 f3 f3 00 00
error 09-Oct-2019 19:28:33 0x10003a843620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
error 09-Oct-2019 19:28:33 0x10003a843630: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 02 f4
error 09-Oct-2019 19:28:33 0x10003a843640: f4 f4 f2 f2 f2 f2 04 f4 f4 f4 f2 f2 f2 f2 00 00
error 09-Oct-2019 19:28:33 0x10003a843650: f4 f4 f2 f2 f2 f2 00 00 00 00 f2 f2 f2 f2 00 00
error 09-Oct-2019 19:28:33 Shadow byte legend (one shadow byte represents 8 application bytes):
error 09-Oct-2019 19:28:33 Addressable: 00
error 09-Oct-2019 19:28:33 Partially addressable: 01 02 03 04 05 06 07
error 09-Oct-2019 19:28:33 Heap left redzone: fa
error 09-Oct-2019 19:28:33 Heap right redzone: fb
error 09-Oct-2019 19:28:33 Freed heap region: fd
error 09-Oct-2019 19:28:33 Stack left redzone: f1
error 09-Oct-2019 19:28:33 Stack mid redzone: f2
error 09-Oct-2019 19:28:33 Stack right redzone: f3
error 09-Oct-2019 19:28:33 Stack partial redzone: f4
error 09-Oct-2019 19:28:33 Stack after return: f5
error 09-Oct-2019 19:28:33 Stack use after scope: f8
error 09-Oct-2019 19:28:33 Global redzone: f9
error 09-Oct-2019 19:28:33 Global init order: f6
error 09-Oct-2019 19:28:33 Poisoned by user: f7
error 09-Oct-2019 19:28:33 Container overflow: fc
error 09-Oct-2019 19:28:33 Array cookie: ac
error 09-Oct-2019 19:28:33 Intra object redzone: bb
error 09-Oct-2019 19:28:33 ASan internal: fe
error 09-Oct-2019 19:28:36 r3: Daemon bgpd not running
This is the result of this code pattern in rfapi/rfapi_import.c:
prefix_cmp((struct prefix *)&bpi_result->extra->vnc.import.rd,
(struct prefix *)prd))
Effectively prd or vnc.import.rd are `struct prefix_rd` which
are being typecast to a `struct prefix`. Not a big deal except commit
1315d74de97be2944d7b005b2f9a50e9ae5eff4d modified the prefix_cmp
function to allow for a sorted prefix_cmp. In prefix_cmp
we were looking at the offset and shift. In the case
of vnc we were passing a prefix length of 64 which is the exact length of
the remaining data structure for struct prefix_rd. So we calculated
a offset of 8 and a shift of 0. The data structures for the prefix
portion happened to be equal to 64 bits of data. So we checked that
with the memcmp got a 0 and promptly read off the end of the data
structure for the numcmp. The fix is if shift is 0 that means thei
the memcmp has checked everything and there is nothing to do.
Please note: We will still crash if we set the prefixlen > then
~312 bits currently( ie if the prefixlen specifies a bit length
longer than the prefix length ). I do not think there is
anything to do here( nor am I sure how to correct this either )
as that we are going to have some severe problems when we muck
up the prefixlen.
Fixes: #5025
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'lib/prefix.c')
-rw-r--r-- | lib/prefix.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/prefix.c b/lib/prefix.c index 35b679ab9..aa6661d7f 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -773,8 +773,18 @@ int prefix_cmp(union prefixconstptr up1, union prefixconstptr up2) if (i) return i; - return numcmp(pp1[offset] & maskbit[shift], - pp2[offset] & maskbit[shift]); + /* + * At this point offset was the same, if we have shift + * that means we still have data to compare, if shift is + * 0 then we are at the end of the data structure + * and should just return, as that we will be accessing + * memory beyond the end of the party zone + */ + if (shift) + return numcmp(pp1[offset] & maskbit[shift], + pp2[offset] & maskbit[shift]); + + return 0; } /* |