[libc-commits] [libc] 3a66446 - [libc] add standalone strtoint/float fuzzers

Michael Jones via libc-commits libc-commits at lists.llvm.org
Fri Feb 10 10:46:26 PST 2023


Author: Michael Jones
Date: 2023-02-10T10:46:21-08:00
New Revision: 3a66446a9a0d866cc5766959c3ab010b01786dee

URL: https://github.com/llvm/llvm-project/commit/3a66446a9a0d866cc5766959c3ab010b01786dee
DIFF: https://github.com/llvm/llvm-project/commit/3a66446a9a0d866cc5766959c3ab010b01786dee.diff

LOG: [libc] add standalone strtoint/float fuzzers

Fuzzing the string to integer and float functions without relying on the
system libc allows for tests to be run in a wider variety of places.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D143616

Added: 
    libc/fuzzing/stdlib/strtofloat_fuzz.cpp
    libc/fuzzing/stdlib/strtointeger_fuzz.cpp

Modified: 
    libc/fuzzing/stdlib/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/fuzzing/stdlib/CMakeLists.txt b/libc/fuzzing/stdlib/CMakeLists.txt
index d28a0d52ad178..4a12af62c028f 100644
--- a/libc/fuzzing/stdlib/CMakeLists.txt
+++ b/libc/fuzzing/stdlib/CMakeLists.txt
@@ -16,6 +16,17 @@ add_libc_fuzzer(
     libc.src.stdlib.atof
 )
 
+add_libc_fuzzer(
+  strtofloat_fuzz
+  SRCS
+    strtofloat_fuzz.cpp
+  DEPENDS
+    libc.src.stdlib.atof
+    libc.src.stdlib.strtof
+    libc.src.stdlib.strtod
+    libc.src.stdlib.strtold
+)
+
 add_libc_fuzzer(
   strtointeger_
diff erential_fuzz
   SRCS
@@ -49,3 +60,17 @@ add_libc_fuzzer(
   COMPILE_OPTIONS
     -DLLVM_LIBC_FUZZ_ATOI_CLEANER_INPUT
 )
+
+add_libc_fuzzer(
+  strtointeger_fuzz
+  SRCS
+    strtointeger_fuzz.cpp
+  DEPENDS
+    libc.src.stdlib.atoi
+    libc.src.stdlib.atol
+    libc.src.stdlib.atoll
+    libc.src.stdlib.strtol
+    libc.src.stdlib.strtoll
+    libc.src.stdlib.strtoul
+    libc.src.stdlib.strtoull
+)

diff  --git a/libc/fuzzing/stdlib/strtofloat_fuzz.cpp b/libc/fuzzing/stdlib/strtofloat_fuzz.cpp
new file mode 100644
index 0000000000000..209d3ee9b3e78
--- /dev/null
+++ b/libc/fuzzing/stdlib/strtofloat_fuzz.cpp
@@ -0,0 +1,50 @@
+//===-- strtofloat_fuzz.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc atof implementation.
+///
+//===----------------------------------------------------------------------===//
+#include "src/stdlib/atof.h"
+#include "src/stdlib/strtod.h"
+#include "src/stdlib/strtof.h"
+#include "src/stdlib/strtold.h"
+#include <stddef.h>
+#include <stdint.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  uint8_t *container = new uint8_t[size + 1];
+  if (!container)
+    __builtin_trap();
+  size_t i;
+
+  for (i = 0; i < size; ++i)
+    container[i] = data[i];
+  container[size] = '\0'; // Add null terminator to container.
+
+  const char *str_ptr = reinterpret_cast<const char *>(container);
+
+  char *out_ptr = nullptr;
+
+  // This fuzzer only checks that the alrogithms didn't read beyond the end of
+  // the string in container. Combined with sanitizers, this will check that the
+  // code is not reading memory beyond what's expected. This test does not make
+  // any attempt to check correctness of the result.
+  auto volatile atof_output = __llvm_libc::atof(str_ptr);
+  auto volatile strtof_output = __llvm_libc::strtof(str_ptr, &out_ptr);
+  if (str_ptr + size < out_ptr)
+    __builtin_trap();
+  auto volatile strtod_output = __llvm_libc::strtod(str_ptr, &out_ptr);
+  if (str_ptr + size < out_ptr)
+    __builtin_trap();
+  auto volatile strtold_output = __llvm_libc::strtold(str_ptr, &out_ptr);
+  if (str_ptr + size < out_ptr)
+    __builtin_trap();
+
+  delete[] container;
+  return 0;
+}

diff  --git a/libc/fuzzing/stdlib/strtointeger_fuzz.cpp b/libc/fuzzing/stdlib/strtointeger_fuzz.cpp
new file mode 100644
index 0000000000000..3880d7b5f9c76
--- /dev/null
+++ b/libc/fuzzing/stdlib/strtointeger_fuzz.cpp
@@ -0,0 +1,70 @@
+//===-- strtointeger_fuzz.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Fuzzing test for llvm-libc atof implementation.
+///
+//===----------------------------------------------------------------------===//
+#include "src/stdlib/atoi.h"
+#include "src/stdlib/atol.h"
+#include "src/stdlib/atoll.h"
+#include "src/stdlib/strtol.h"
+#include "src/stdlib/strtoll.h"
+#include "src/stdlib/strtoul.h"
+#include "src/stdlib/strtoull.h"
+#include <stddef.h>
+#include <stdint.h>
+
+// This takes the randomized bytes in data and interprets the first byte as the
+// base for the string to integer conversion and the rest of them as a string to
+// be passed to the string to integer conversion.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  size_t container_size = 0;
+  if (size == 0) {
+    container_size = 1;
+  } else {
+    container_size = size;
+  }
+  uint8_t *container = new uint8_t[container_size];
+  if (!container)
+    __builtin_trap();
+
+  int base = 0;
+  if (size > 0) {
+    base = data[0] % 36;
+    base = base + ((base == 0) ? 0 : 1);
+  }
+  for (size_t i = 1; i < size; ++i) {
+    container[i - 1] = data[i];
+  }
+
+  container[container_size - 1] = '\0'; // Add null terminator to container.
+
+  const char *str_ptr = reinterpret_cast<const char *>(container);
+
+  char *out_ptr = nullptr;
+
+  auto volatile atoi_output = __llvm_libc::atoi(str_ptr);
+  auto volatile atol_output = __llvm_libc::atol(str_ptr);
+  auto volatile atoll_output = __llvm_libc::atoll(str_ptr);
+  auto volatile strtol_output = __llvm_libc::strtol(str_ptr, &out_ptr, base);
+  if (str_ptr + container_size - 1 < out_ptr)
+    __builtin_trap();
+  auto volatile strtoll_output = __llvm_libc::strtoll(str_ptr, &out_ptr, base);
+  if (str_ptr + container_size - 1 < out_ptr)
+    __builtin_trap();
+  auto volatile strtoul_output = __llvm_libc::strtoul(str_ptr, &out_ptr, base);
+  if (str_ptr + container_size - 1 < out_ptr)
+    __builtin_trap();
+  auto volatile strtoull_output =
+      __llvm_libc::strtoull(str_ptr, &out_ptr, base);
+  if (str_ptr + container_size - 1 < out_ptr)
+    __builtin_trap();
+
+  delete[] container;
+  return 0;
+}


        


More information about the libc-commits mailing list