Donald Sharp [Wed, 4 Aug 2021 14:55:39 +0000 (10:55 -0400)]
zebra: Ensure stream meets some level of stringency for fuzzing
In the fuzzing code we cut to the chase and call zserv_handle_commands
which bypasses the basic parsing correctness done in zserv_read
duplicate some of this code in the zserv_handle_commands function
so we can throw away blatantly bad packages.
Donald Sharp [Tue, 3 Aug 2021 19:51:59 +0000 (15:51 -0400)]
ospfd: Do not leak memory when fuzzing
When executing a fuzzing target there exists a code path
where we allocate memory and then drop it immediately
because the fuzzing does not actually schedule threads of
execution.
Quentin Young [Wed, 19 Feb 2020 21:52:00 +0000 (16:52 -0500)]
zebra: handle gr weirdness under libFuzzer
Two workarounds here. The #ifndef around assert(0) is to get around a
bug, in which a client that connects, announces GR capability,
disconnects, reconnects then sends anything other than a ZAPI hello will
hit the assert. GR resync is done in zread_hello(), so if a reconnecting
client doesn't send a hello then GR will notice that it's received a
disonnect for the same client twice in a row and assert. This is a bug,
GR should be able to handle that.
The rest of the code works around GR having a timer-based memory free.
Since we've disabled all thread.h code to increase determinism and avoid
mutex locks and other weirdness, clients repeatedly announcing GR
capability messages will result in a soft memleak.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Quentin Young [Fri, 17 Jan 2020 15:23:24 +0000 (10:23 -0500)]
bgpd: clean up some libfuzzer / afl stuff
- Unify the paths a bit more
- Switch to maintaining the peer and not deleting it after each packet;
this increased coverage in zebra a lot, might help here
- Free processed packets, in libfuzzer case so we dont leak them
- Add check that size is at least BGP_HEADER_SIZE, validate_header()
assumes it
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Quentin Young [Mon, 13 Jan 2020 20:25:02 +0000 (15:25 -0500)]
tweak configure options for --enable-libfuzzer
* Compile (but don't link) with libfuzzer support for all daemons - this
is -fsanitize=fuzzer-no-link
* Remove forcing ASAN for libfuzzer - better to control which sanitizer
you want with --enable-<sanitizer>
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Quentin Young [Mon, 13 Jan 2020 20:20:01 +0000 (15:20 -0500)]
bgpd: cleanup suboptimal AFL paths after libFuzzer
The AFL path through LLVMFuzzerTestOneInput is running a bit slow
because we are initializing BGP twice. Fix this. Also, since we know at
compile time whether we need to create a peer (libFuzzer) or use one
created already (AFL fork() case) we can save a branch in the hot path,
so let's do that.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Quentin Young [Sat, 11 Jan 2020 03:20:33 +0000 (22:20 -0500)]
enable libfuzzer for bgpd
Wow that was painful
libFuzzer replaces main(), so while we can compile with
-fsanitize=fuzzer, we can't link with it unless we have a way to
undefine main(). So I've added a #define, FUZZING_LIBFUZZER, that
daemons who want to support libfuzzer need to guard their main() with.
This also means we can't use the SAN_FLAGS automake variable, since that
is included in both AM_CFLAGS and AM_LDFLAGS, to add -fsanitize=fuzzer
to. We need new daemon specific flags. Actually, we can add
-fsanitize=fuzzer-no-link to SAN_FLAGS, but we need daemon specific
LDFLAGS so we can control who links with -fsanitize=fuzzer. Aside from
replacing main(), LibFuzzer.a also needs to link to a user-defined
function called `LLVMFuzzerTestOneInput` which is the fuzzer entrypoint.
For bgpd, because libfuzzer is in-process, we now need to actuall clean
up after ourselves each fuzz run to avoid leaking memory. We also can't
touch global state. This also means we run slower because we have to
create and destroy a peer struct every iteration.
Finally I've almost certainly broken afl for now, will fix later.
Quentin Young [Sat, 11 Jan 2020 03:20:33 +0000 (22:20 -0500)]
enable libfuzzer for bgpd
Wow that was painful
libFuzzer replaces main(), so while we can compile with
-fsanitize=fuzzer, we can't link with it unless we have a way to
undefine main(). So I've added a #define, FUZZING_LIBFUZZER, that
daemons who want to support libfuzzer need to guard their main() with.
This also means we can't use the SAN_FLAGS automake variable, since that
is included in both AM_CFLAGS and AM_LDFLAGS, to add -fsanitize=fuzzer
to. We need new daemon specific flags. Actually, we can add
-fsanitize=fuzzer-no-link to SAN_FLAGS, but we need daemon specific
LDFLAGS so we can control who links with -fsanitize=fuzzer.
Also, compiling with libfuzzer also requires that you define a function
named LLVMFuzzerTestOneInput(). So I defined a stub version in libfrr.c
and added a macro to undefine it for daemons who actually implement it.
Now that I write it down this probably isn't necessary at all given the
previous paragraph. I think that function is only checked for at link
time.
For bgpd, because libfuzzer is in-process, we now need to actuall clean
up after ourselves each fuzz run to avoid leaking memory. We also can't
touch global state. This also means we run slower because we have to
create and destroy a peer struct every iteration.
Finally I've almost certainly broken afl for now, will fix later.
Quentin Young [Thu, 2 Jan 2020 07:02:31 +0000 (02:02 -0500)]
bgpd: enable deferred forkserver mode
Having narrowed down the issue with deferred mode to capability privs,
and having disabled those, we can now use afl deferred mode for...10x
performance gainz?!?!? zomg!
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Quentin Young [Thu, 12 Dec 2019 19:53:06 +0000 (14:53 -0500)]
ospfd allow fuzzing LSUPD, LSACK, LSREQ packets
- Anything except HELLO wants a neighbor created, so do that
- Skip some unnecessary stuff
- Most stuff checks the LSDB and returns early, so skip those
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Quentin Young [Thu, 21 Nov 2019 04:35:44 +0000 (23:35 -0500)]
bgpd: add checks performed by i/o code
Getting some false positives from AFL because we aren't performing
checks that are performed by the I/O thread before the packet processor
is ever invoked. Add those checks.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Quentin Young [Fri, 12 Nov 2021 19:45:36 +0000 (14:45 -0500)]
doc: update & clarify language in process arch doc
There was a historical blurb at the top of the process architecture
document that in several instances caused some confusion regarding
whether or not FRR supports multithreading. Remove this paragraph and
replace it with a summary of the page contents.
Donald Sharp [Fri, 12 Nov 2021 15:52:03 +0000 (10:52 -0500)]
tests: Ensure BGP has had time to import routes through the vpn
Currently I get bgp_instance_del-test as well as bgp_l3vpn_to_bgp_vrf
failures every ~3-4 runs when under a 40 parallel run with micronet.
Examination of the failure and passing cases always leads to the
failures showing convergence of bgp bestpath immediately after
the show commands to ensure that the routes are there.
Modify the code to look for the fact that the vrf has
converged from routes being passed around across vrf's
and ensure that bestpath has run on them.
Igor Ryzhov [Fri, 12 Nov 2021 16:32:06 +0000 (19:32 +0300)]
bgpd: fix source-address for BFD sessions when using update-source IFNAME
When "update-source IFNAME" is used for the neighbor, p->update_source
is set to NULL, so we can't use it as a source address and should use
the address from p->su_local.