Repository: google/clusterfuzz

Issue:
AFL++ fuzzers not uploading corpus
From Jonathan Metzman:
Nothing is getting added to corpus because in the merge implementation ClusterFuzz thinks every testcase covers the same code


Discussion:
I think it thinks this because showmap is broken.
I think I can reproduce this with an AFL++ build on my desktop. I'm going to confirm when I get a chance and file an issue with AFL++.
Fix posted here: https://github.com/AFLplusplus/AFLplusplus/issues/1452 will add this to CF soon.

Resolving patch:
diff --git a/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py b/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py
--- a/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py
+++ b/src/clusterfuzz/_internal/bot/fuzzers/afl/launcher.py
@@ -1030,7 +1030,7 @@ def merge_corpus(self):
     self._executable_path = self.afl_showmap_path
     # Hack around minijail.
     showmap_args = self._fuzz_args
-    showmap_args[-1] = '1'
+    showmap_args[-1] = '-'
     # Remove arguments that are just for afl-fuzz.
     self.remove_arg(showmap_args, constants.DICT_FLAG)
     self.remove_arg(showmap_args, constants.INPUT_FLAG)


Test patch:
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/afl_launcher_integration_test.py b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/afl_launcher_integration_test.py
--- a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/afl_launcher_integration_test.py
+++ b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/afl_launcher_integration_test.py
@@ -207,9 +207,6 @@ def _test_libfuzzerize_corpus(self, mock_get_timeout):
             # 'idCOLON000000,larger_same_cov_idCOLON000001,non_initial_cov'.
             # This filename is the hash of idCOLON000001,non_initial_cov.
             '3dce8306f3c1810d5d81ed5ebb0ccea947277a61',
-            # This file reaches unique paths and should therefore be merged.
-            # This filename is the hash of idCOLON000002,unique_cov.
-            '4c1fe29b1a967d34a6fcc078b8fb653dd807dee7',
             # Ensure we aren't removing anything from the input corpus. Thus
             # even though 'in1' and 'nearly_empty' are redundant they should
             # both be here Similarly, even though 'in1' and 'nearly_empty' have
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer
Binary files a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer and b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer differ
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer.cc b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer.cc
--- a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer.cc
+++ b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/always_crash_fuzzer.cc
@@ -13,11 +13,13 @@
 // limitations under the License.
 
 #include <cstdint>
+#include <cstdio>
 #include <cstdlib>
 
 void Foo() {
   static int count = 0;
   count++;
+  printf("%d\n", count);
 
   if (count >= 5) {
     *(volatile uint8_t*)0 = 0;
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/assert_fail b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/assert_fail
Binary files a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/assert_fail and b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/assert_fail differ
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer
Binary files a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer and b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer differ
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer.cc b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer.cc
--- a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer.cc
+++ b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/easy_crash_fuzzer.cc
@@ -13,10 +13,12 @@
 // limitations under the License.
 
 #include <cstdint>
+#include <cstdio>
 #include <cstdlib>
 
 void uaf() {
   int* a = new int[42];
+  printf("%p\n", a);
   delete[] a;
 
   *a = 42;
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/return_code_255 b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/return_code_255
Binary files a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/return_code_255 and b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/return_code_255 differ
diff --git a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/test_fuzzer b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/test_fuzzer
Binary files a/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/test_fuzzer and b/src/clusterfuzz/_internal/tests/core/bot/fuzzers/afl/data/test_fuzzer differ