summaryrefslogtreecommitdiff
path: root/doc/developer
diff options
context:
space:
mode:
Diffstat (limited to 'doc/developer')
-rw-r--r--doc/developer/building-frr-for-openwrt.rst4
-rw-r--r--doc/developer/frr-release-procedure.rst49
-rw-r--r--doc/developer/fuzzing.rst164
-rw-r--r--doc/developer/index.rst1
-rw-r--r--doc/developer/topotests-jsontopo.rst2
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,