diff options
Diffstat (limited to 'doc/developer')
| -rw-r--r-- | doc/developer/building-frr-for-openwrt.rst | 4 | ||||
| -rw-r--r-- | doc/developer/frr-release-procedure.rst | 49 | ||||
| -rw-r--r-- | doc/developer/fuzzing.rst | 164 | ||||
| -rw-r--r-- | doc/developer/index.rst | 1 | ||||
| -rw-r--r-- | doc/developer/topotests-jsontopo.rst | 2 |
5 files changed, 198 insertions, 22 deletions
diff --git a/doc/developer/building-frr-for-openwrt.rst b/doc/developer/building-frr-for-openwrt.rst index 9bd1296dad..47cf2cbd43 100644 --- a/doc/developer/building-frr-for-openwrt.rst +++ b/doc/developer/building-frr-for-openwrt.rst @@ -51,7 +51,7 @@ to work and it may be needed to run a ``make`` for the entire build environment. Add ``V=s`` to get more debugging output. More information about OpenWrt buildsystem can be found `here -<https://openwrt.org/docs/guide-developer/build-system/use-buildsystem>`_. +<https://openwrt.org/docs/guide-developer/build-system/use-buildsystem>`__. Work with sources ----------------- @@ -59,7 +59,7 @@ Work with sources To update to a newer version, or change other options, you need to edit the ``feeds/packages/frr/Makefile``. More information about working with patches in OpenWrt buildsystem can be found `here -<https://openwrt.org/docs/guide-developer/build-system/use-patches-with-buildsystem>`_. +<https://openwrt.org/docs/guide-developer/build-system/use-patches-with-buildsystem>`__. Usage ----- diff --git a/doc/developer/frr-release-procedure.rst b/doc/developer/frr-release-procedure.rst index ff95aa04a9..5da73f61f6 100644 --- a/doc/developer/frr-release-procedure.rst +++ b/doc/developer/frr-release-procedure.rst @@ -20,7 +20,13 @@ FRR Release Procedure git checkout -b stable/<version> git push origin stable/<version>:refs/heads/stable/<version> -3. Update Changelog for Red Hat Packages: +3. Remove the development branch called ``dev/<version>`` + + .. code-block:: console + + git push origin --delete dev/<version> + +4. Update Changelog for Red Hat Packages: Edit :file:`redhat/frr.spec.in` and look for the ``%changelog`` section: @@ -41,7 +47,7 @@ FRR Release Procedure - Add the changelog text below this entry. -4. Update Changelog for Debian Packages: +5. Update Changelog for Debian Packages: Edit :file:`changelog-auto.in`: @@ -83,41 +89,41 @@ FRR Release Procedure . * Your Changes Here -5. Change main version number: +6. Change main version number: - Edit :file:`configure.ac` and change version in the ``AC_INIT`` command to ``<version>`` -6. Commit the changes, adding the changelog to the commit message. Follow all +7. Commit the changes, adding the changelog to the commit message. Follow all existing commit guidelines. -7. Create and submit a GitHub pull request, with the ``HEAD`` set to +8. Create and submit a GitHub pull request, with the ``HEAD`` set to ``stable/<version>`` and the base set to the upstream ``master`` branch. Allow NetDef CI to complete its run and verify that all package builds were successful. -8. Create a git tag for the version: +9. Create a git tag for the version: .. code-block:: console git tag -a frr-<version> -m "FRRouting Release <version>" -9. Push the commit and new tag. +10. Push the commit and new tag. .. code-block:: console git push origin stable/<version>:refs/head/stable/<version> git push origin frr-<version> -10. Kick off the Release build plan on the CI system for the correct release. +11. Kick off the Release build plan on the CI system for the correct release. Contact Martin Winter for this step. Ensure all release packages build successfully. -11. Kick off the Snapcraft build plan for the release. +12. Kick off the Snapcraft build plan for the release. -12. Acquire the release RPM binary packages from Martin Winter. +13. Acquire the release RPM binary packages from Martin Winter. -13. On GitHub, go to the <https://github.com/FRRouting/frr/releases>_ and click +14. On GitHub, go to the <https://github.com/FRRouting/frr/releases>_ and click "Draft a new release". Write a release announcement. The release announcement should follow the template in ``release-announcement-template.md``, located next to this document. Check @@ -129,27 +135,27 @@ FRR Release Procedure attach source tarballs - these will be generated and attached by GitHub automatically. Do not publish the release yet. -14. Contact the current Debian maintainer for FRR to get new Debian packages +15. Contact the current Debian maintainer for FRR to get new Debian packages built and published on our APT repository at https://deb.frrouting.net/. Ensure the webpage text is updated. Verify that new packages install successfully on a vanilla Debian installation using the instructions on the webpage. -15. Deploy Snapcraft release (after CI system finishes the tests for snapcraft +16. Deploy Snapcraft release (after CI system finishes the tests for snapcraft testplan). -16. Update the Read The Docs instance to being publishing documentation built +17. Update the Read The Docs instance to being publishing documentation built off the ``stable/<version>`` branch. Contact Quentin Young for this step. -17. Publish the GitHub release. +18. Publish the GitHub release. -18. Clone the ``frr-www`` repository: +19. Clone the ``frr-www`` repository: .. code-block:: console git clone https://github.com/FRRouting/frr-www.git -19. Add a new release announcement, using a previous announcement as template: +20. Add a new release announcement, using a previous announcement as template: .. code-block:: console @@ -174,8 +180,13 @@ FRR Release Procedure Once finished, manually add a new entry into ``index.html`` to link to this new announcement. Look at past commits to see how to do this. -20. Deploy the updated ``frr-www`` on the frrouting.org web server and verify +21. Deploy the updated ``frr-www`` on the frrouting.org web server and verify that the announcement text is visible. -21. Send an email to ``announce@lists.frrouting.org``. The text of this email +22. Send an email to ``announce@lists.frrouting.org``. The text of this email should include the text from the GitHub release. + +23. Update masters version of the changelog-auto.in + + Take the change data and cut-n-paste the changes into the master version below + the @VERSION@-0 lines. So we have the history of the previous release. diff --git a/doc/developer/fuzzing.rst b/doc/developer/fuzzing.rst new file mode 100644 index 0000000000..8a3318745e --- /dev/null +++ b/doc/developer/fuzzing.rst @@ -0,0 +1,164 @@ +.. _fuzzing: + +Fuzzing +======= + +This page describes the fuzzing targets and supported fuzzers available in FRR +and how to use them. Familiarity with fuzzing techniques and tools is assumed. + +Overview +-------- + +It is well known that networked applications tend to be difficult to fuzz on +their network-facing attack surfaces. Approaches involving actual network +transmission tend to be slow and are subject to intermediate devices and +networking stacks which tend to drop fuzzed packets, especially if the fuzzing +surface covers IP itself. Some time was spent on fuzzing FRR this way with some +mediocre results but attention quickly turned towards skipping the actual +networking and instead adding fuzzing targets directly in the packet processing +code for use by more traditional in- and out-of-process fuzzers. Results from +this approach have been very fruitful. + +The patches to add fuzzing targets are kept in a separate git branch. Typically +it is better to keep them in the main branch so they are kept up to date and do +not need to be constantly synchronized with the main codebase. Unfortunately, +changes to FRR to support fuzzing necessarily extend far beyond the +entrypoints. Checksums must be disarmed, interactions with the kernel must be +skipped, sockets and files must be avoided, desired under/overflows must be +marked, etc. There are the usual ``LD_PRELOAD`` libraries to emulate these +things (preeny et al) but FRR is a very kernel-reliant program and these +libraries tend to create annoying problems when used with FRR for whatever +reason. Keeping this code in the main codebase is cluttering, difficult to work +with / around, and runs the risk of accidentally introducing bugs even if +``#ifdef``'d out. Consequently it's in a separate branch that is rebased on +``master`` from time to time. + + +Code +---- + +The git branch with fuzzing targets is located here: + +https://github.com/FRRouting/frr/tree/fuzz + +To build libFuzzer targets, pass ``--enable-libfuzzer`` to ``configure``. +To build AFL targets, compile with ``afl-clang`` as usual. + +Fuzzing with sanitizers is strongly recommended, especially ASAN, which you can +enable by passing ``--enable-address-sanitizer`` to ``configure``. + +Suggested UBSAN flags: ``-fsanitize-recover=unsigned-integer-overflow,implicit-conversion -fsanitize=unsigned-integer-overflow,implicit-conversion,nullability-arg,nullability-assign,nullability-return`` +Recommended cflags: ``-Wno-all -g3 -O3 -funroll-loops`` + +Design +------ + +All fuzzing targets have support for libFuzzer and AFL. This is done by writing +the target as a libFuzzer entrypoint (``LLVMFuzzerTestOneInput()``) and calling +it from the AFL entrypoint in ``main()``. New targets should use this rule. + +When adding AFL entrypoints, it's a good idea to use AFL persistent mode for +better performance. Grep ``bgpd/bgp_main.c`` for ``__AFL_INIT()`` for an +example of how to do this in FRR. Typically it involves moving all internal +daemon setup into a setup function. Then this setup function is called exactly +once for the lifetime of the process. In ``LLVMFuzzerTestOneInput()`` this +means you need to call it at the start of the function protected by a static +boolean that is set to true, since that function is your entrypoint. You also +need to call it prior to ``__AFL_INIT()`` in ``main()`` because ``main()`` is +your entrypoint in the AFL case. + +Adding support to daemons +^^^^^^^^^^^^^^^^^^^^^^^^^ + +This section describes how to add entrypoints to daemons that do not have any +yet. + +Because libFuzzer has its own ``main()`` function, when adding fuzzing support +to a daemon that doesn't have any targets already, ``main()`` needs to be +``#ifdef``'d out like so: + +.. code:: c + + #ifndef FUZZING_LIBFUZZER + + int main(int argc, char **argv) + { + ... + } + + #endif /* FUZZING_LIBFUZZER */ + + +The ``FUZZING_LIBFUZZER`` macro is set by ``--enable-libfuzzer``. + +Because libFuzzer can only be linked into daemons that have +``LLVMFuzzerTestOneInput()`` implemented, we can't pass ``-fsanitize=fuzzer`` +to all daemons in ``AM_CFLAGS``. It needs to go into a variable specific to +each daemon. Since it can be thought of as a kind of sanitizer, for daemons +that have libFuzzer support there are now individual flags variables for those +daemons named ``DAEMON_SAN_FLAGS`` (e.g. ``BGPD_SAN_FLAGS``, +``ZEBRA_SAN_FLAGS``). This variable has the contents of the generic +``SAN_FLAGS`` plus any fuzzing-related flags. It is used in daemons' +``subdir.am`` in place of ``SAN_FLAGS``. Daemons that don't support libFuzzer +still use ``SAN_FLAGS``. If you want to add fuzzing support to a daemon you +need to do this flag variable conversion; look at ``configure.ac`` for +examples, it is fairly straightforward. Remember to update ``subdir.am`` to use +the new variable. + +Do note that when fuzzing is enabled, ``SAN_FLAGS`` gains +``-fsanitize=fuzzer-no-link``; the result is that all daemons are instrumented +for fuzzing but only the ones with ``LLVMFuzzerTestOneInput()`` actually get +linked with libFuzzer. + + +Targets +------- + +A given daemon can have lots of different paths that are interesting to fuzz. +There's not really a great way to handle this, most fuzzers assume the program +has one entrypoint. The approach taken in FRR for multiple entrypoints is to +control which path is taken within ``LLVMFuzzerTestOneInput()`` using +``#ifdef`` and passing whatever controlling macro definition you want. Take a +look at that function for the daemon you're interested in fuzzing, pick the +target, add ``#define MY_TARGET 1`` somewhere before the ``#ifdef`` switch, +recompile. + +.. list-table:: Fuzzing Targets + + * - Daemon + - Target + - Fuzzers + * - bgpd + - packet parser + - libfuzzer, afl + * - ospfd + - packet parser + - libfuzzer, afl + * - pimd + - packet parser + - libfuzzer, afl + * - vrrpd + - packet parser + - libfuzzer, afl + * - vrrpd + - zapi parser + - libfuzzer, afl + * - zebra + - netlink + - libfuzzer, afl + * - zebra + - zserv / zapi + - libfuzzer, afl + + +Fuzzer Notes +------------ + +Some interesting seed corpuses for various daemons are available `here +<https://github.com/qlyoung/frr-fuzz/tree/master/samples>`_. + +For libFuzzer, you need to pass ``-rss_limit_mb=0`` if you are fuzzing with +ASAN enabled, as you should. + +For AFL, afl++ is strongly recommended; afl proper isn't really maintained +anymore. diff --git a/doc/developer/index.rst b/doc/developer/index.rst index 1ba0f31c8a..5a7da806ff 100644 --- a/doc/developer/index.rst +++ b/doc/developer/index.rst @@ -9,6 +9,7 @@ FRRouting Developer's Guide packaging process-architecture library + fuzzing tracing testing bgpd diff --git a/doc/developer/topotests-jsontopo.rst b/doc/developer/topotests-jsontopo.rst index 1c77cd7be1..07f1f05114 100644 --- a/doc/developer/topotests-jsontopo.rst +++ b/doc/developer/topotests-jsontopo.rst @@ -95,7 +95,7 @@ The first step to write a new test is to define the topology and initial configuration. User has to define topology and initial configuration in JSON file. Here is an example of JSON file:: - BGP neihghborship with single phy-link, sample JSON file: + BGP neighborship with single phy-link, sample JSON file: { "ipv4base": "192.168.0.0", "ipv4mask": 30, |
