]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[experiments/fuzz] Documentation updated.
authorTomek Mrugalski <tomasz@isc.org>
Mon, 21 Nov 2016 12:22:58 +0000 (13:22 +0100)
committerTomek Mrugalski <tomasz@isc.org>
Wed, 24 Apr 2019 10:43:05 +0000 (12:43 +0200)
doc/fuzz.txt
src/bin/dhcp6/fuzz.cc

index 5f55e30054b624927bbf517b1f5e0db2ff3117e1..533e06aa4e57ee4980596b95eafddb4a9c39dc98 100644 (file)
@@ -15,8 +15,8 @@ Ubuntu 16.04 I had to do this:
 
 3. Set up path to AFL binaries
 
EXPORT AFL_PATH=/home/thomson/devel/afl-2.35b
EXPORT PATH=$PATH:/home/thomson/devel/afl-2.35b
export AFL_PATH=/home/thomson/devel/afl-2.35b
export PATH=$PATH:/home/thomson/devel/afl-2.35b
 
 4. Build Kea using AFL
 
@@ -24,13 +24,13 @@ Ubuntu 16.04 I had to do this:
  git pull
  git checkout experiments/fuzz
  autoreconf -i
- CXX=afl-clang-fast++ ./configure --enable-fuzz
+ CXX=afl-clang-fast++ ./configure --enable-fuzz --enable-static-link
  make
 
  Note: no unit-tests needed. We will be fuzzing the
  production code only.
 
-5. Run fuzzer
+5. Configure destination address
 
  The defaults (see src/bin/dhcp6/fuzz.cc) are:
  interface: eth0
@@ -45,4 +45,31 @@ Ubuntu 16.04 I had to do this:
  E.g.
  export KEA_AFL_INTERFACE=eth1
 
+6. Run fuzzer
+
+ Set up max size of a virtual memory allowed to 4GB:
+ ulimit -v 4096000
+
+ Instruct AFL to allow 4096MB of virtual memory and run AFL:
+ afl-fuzz -m 4096 -i tests/fuzz-data -o fuzz-out ./kea-dhcp6 -c fuzz.json
+
+ Here's what the switches do:
+ -m 4096 - allow Kea to take up to 4GB memory
+ -i tests/fuzz-data - Input seeds. These are the packet files used
+    to initiate the packet randomization. Several examples are in
+    src/bin/dhcp6/tests/fuzz-data. You can extract them using wireshark,
+    right click on a packet, then export as binary data. Make sure you
+    export the payload of UDP content. the first exported byte should
+    by message-type.
+ -o dir - that's the output directory. It doesn't have to exist.
+
+7. Checking that the fuzzer is really working
+
+ a) the harness prints out a line to /tmp/kea-fuzz-harness.txt every
+ time a new packet is sent. This generated 4,5MB of entries in 20
+ minutes. Obviously, this has to be disabled for production fuzzing,
+ but it's good for initial trials.
+
+ b) I have my fuzz.json (which is renamed doc/examples/kea6/simple.json)
+ that tell Kea to use logging on level INFO and write output to a
+ file. This file keeps growing. That's around 3,8MB after 20 minutes.
index 2e8be8f0c39609fb25b55400d16e2df666285247..43071b138e46b071d74a3f36a565da64da7d0638 100644 (file)
@@ -18,6 +18,7 @@
 #include <dhcp/dhcp6.h>
 
 #include <iostream>
+#include <fstream>
 
 #include <stdlib.h>
 #include <string.h>
@@ -27,6 +28,7 @@
 #include <unistd.h>
 #include <pthread.h>
 
+
 #ifndef __AFL_LOOP
 #error To use American Fuzzy Lop you have to set CC to afl-clang-fast!!!
 #endif
@@ -59,6 +61,8 @@ kea_main_client(void *arg) {
     string dst(ALL_DHCP_RELAY_AGENTS_AND_SERVERS);
     string port("547");
 
+    ofstream f("/tmp/kea-fuzz-harness.txt", ios::ate);
+
     const char *iface_ptr = getenv("KEA_AFL_INTERFACE");
     if (iface_ptr) {
         iface = string(iface_ptr);
@@ -76,17 +80,17 @@ kea_main_client(void *arg) {
 
     unsigned int iface_id = if_nametoindex(iface.c_str());
     
-    cout << "Kea AFL setup:" << endl;
-    cout << "Interface: " << iface << endl;
-    cout << "Interface index: " << iface_id << endl;
-    cout << "UDP destination addr: " << dst << endl;
-    cout << "UDP destination port: " << port << endl;
+    f << "Kea AFL setup:" << endl;
+    f << "Interface: " << iface << endl;
+    f << "Interface index: " << iface_id << endl;
+    f << "UDP destination addr: " << dst << endl;
+    f << "UDP destination port: " << port << endl;
 
     memset(&servaddr, 0, sizeof (servaddr));
     servaddr.sin6_family = AF_INET6;
     if (inet_pton(AF_INET6, dst.c_str(), &servaddr.sin6_addr) != 1) {
-        cout << "Error: inet_pton() failed: can't convert " << dst
-             << " to address." << endl;
+        f << "Error: inet_pton() failed: can't convert " << dst
+          << " to address." << endl;
         exit(EXIT_FAILURE);
     }
     servaddr.sin6_port = htons(547);
@@ -94,13 +98,13 @@ kea_main_client(void *arg) {
 
     sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
     if (sockfd < 0) {
-        cout << "Failed to create UDP6 socket" << endl;
+        f << "Failed to create UDP6 socket" << endl;
         exit(EXIT_FAILURE);
     }
 
     buf = malloc(65536);
     if (!buf) {
-        cout << "Failed to allocate a buffer" << endl;
+        f << "Failed to allocate a buffer" << endl;
         exit(EXIT_FAILURE);
     }
 
@@ -126,21 +130,21 @@ kea_main_client(void *arg) {
             } */
 
         if (pthread_mutex_lock(&mutex) != 0) {
-            cout << "#### Failed to lock mutex" << endl;
+            f << "#### Failed to lock mutex" << endl;
         }
 
         ready = false;
 
         ssize_t sent;
 
-        cout << "Sending " << length << " bytes to " << dst << "/" << port
-             << " over " << iface << "/" << iface_id << endl;
+        f << "Sending " << length << " bytes to " << dst << "/" << port
+          << " over " << iface << "/" << iface_id << endl;
 
         sent = sendto(sockfd, buf, length, 0,
                       (struct sockaddr *) &servaddr, sizeof(servaddr));
         if (sent != length) {
-            cout << "#### Error: expected to send " << length
-                 << ", but really sent " << sent << endl;
+            f << "#### Error: expected to send " << length
+              << ", but really sent " << sent << endl;
         }
 
         /* unclog */
@@ -150,7 +154,7 @@ kea_main_client(void *arg) {
             pthread_cond_wait(&cond, &mutex);
 
         if (pthread_mutex_unlock(&mutex) != 0) {
-            cout << "#### Failed to unlock mutex" << endl;
+            f << "#### Failed to unlock mutex" << endl;
         }
     }