[libc-commits] [PATCH] D82427: [libc] Fix strcmp fuzz test to use one input.

Chris Gyurgyik via Phabricator via libc-commits libc-commits at lists.llvm.org
Fri Jun 26 12:36:01 PDT 2020


cgyurgyik updated this revision to Diff 273810.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82427/new/

https://reviews.llvm.org/D82427

Files:
  libc/fuzzing/string/strcmp_fuzz.cpp


Index: libc/fuzzing/string/strcmp_fuzz.cpp
===================================================================
--- libc/fuzzing/string/strcmp_fuzz.cpp
+++ libc/fuzzing/string/strcmp_fuzz.cpp
@@ -13,31 +13,62 @@
 #include <stddef.h>
 #include <stdint.h>
 
-extern "C" int LLVMFuzzerTestTwoInputs(const uint8_t *data1, size_t size1,
-                                       const uint8_t *data2, size_t size2) {
-  // Verify each data source contains at least one character.
-  if (!size1 || !size2)
+// The general structure is to take the value of the first byte, set size1 to
+// that value, and add the null terminator. size2 will then contain the rest of
+// the bytes in data. For example, with inputs ([2, 6, 4, 8, 0], 5):
+//         size1: data[0] = 2
+//         data1: [2, 6] + '\0' = [2, 6, '\0']
+//         size2: size - size1 = 3
+//         data2: [4, 8, '\0']
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  // Verify the size is at least 1.
+  if (!size)
     return 0;
-  // Verify that the final character is the null terminator.
-  if (data1[size1 - 1] != '\0' || data2[size2 - 1] != '\0')
+
+  const size_t size1 = (data[0] <= size ? data[0] : size);
+  const size_t size2 = size - size1;
+
+  // The first size will always be at least 1 since
+  // we need to append the null terminator. The second size
+  // needs to be checked since it must also contain the null
+  // terminator.
+  if (!size2)
+    return 0;
+
+  // Copy the data into new containers.
+  // Add one for null terminator.
+  uint8_t *data1 = new uint8_t[size1 + 1];
+  if (!data1)
+    __builtin_trap();
+  size_t i;
+  for (i = 0; i < size1; ++i)
+    data1[i] = data[i];
+  data1[size1] = '\0'; // Add null terminator to data1.
+
+  uint8_t *data2 = new uint8_t[size2];
+  if (!data2)
+    __builtin_trap();
+  for (size_t j = 0; j < size2; ++i, ++j)
+    data2[j] = data[i];
+  // Verify the second string is null-terminated.
+  if (data2[size2 - 1] != '\0')
     return 0;
 
   const char *s1 = reinterpret_cast<const char *>(data1);
   const char *s2 = reinterpret_cast<const char *>(data2);
 
-  const size_t minimum_size = size1 < size2 ? size1 : size2;
-
   // Iterate through until either the minimum size is hit,
   // a character is the null terminator, or the first set
   // of differed bytes between s1 and s2 are found.
   // No bytes following a null byte should be compared.
-  size_t i;
-  for (i = 0; i < minimum_size; ++i) {
-    if (!s1[i] || s1[i] != s2[i])
+  const size_t minimum_size = size1 < size2 ? size1 : size2;
+  size_t k;
+  for (k = 0; k < minimum_size; ++k) {
+    if (!s1[k] || s1[k] != s2[k])
       break;
   }
 
-  int expected_result = s1[i] - s2[i];
+  int expected_result = s1[k] - s2[k];
   int actual_result = __llvm_libc::strcmp(s1, s2);
 
   // The expected result should be the difference between the first non-equal
@@ -48,10 +79,13 @@
 
   // Verify reversed operands. This should be the negated value of the previous
   // result, except of course if the previous result was zero.
-  expected_result = s2[i] - s1[i];
+  expected_result = s2[k] - s1[k];
   actual_result = __llvm_libc::strcmp(s2, s1);
   if (expected_result != actual_result)
     __builtin_trap();
 
+  delete[] data1;
+  delete[] data2;
+
   return 0;
-}
+}
\ No newline at end of file


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D82427.273810.patch
Type: text/x-patch
Size: 3324 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20200626/cc128d1e/attachment.bin>


More information about the libc-commits mailing list