]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: Fix read beyond end of data structure
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 10 Oct 2019 12:52:54 +0000 (08:52 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 15 Oct 2019 17:20:42 +0000 (13:20 -0400)
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>
lib/prefix.c

index 35b679ab90fbef48a76c2c3f74cb96f3be95307f..aa6661d7fb799a9a9aa9e01f46b863601e394cbd 100644 (file)
@@ -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;
 }
 
 /*