[libc-commits] [libc] [libc] Add a differential fuzzer for inet_aton (PR #200341)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Mon Jun 8 07:04:22 PDT 2026


https://github.com/labath updated https://github.com/llvm/llvm-project/pull/200341

>From fb3c8f5d3b3f12b6aa9f26669c847e98e37a5a19 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Fri, 15 May 2026 16:10:31 +0000
Subject: [PATCH 1/2] [libc] Add a differential fuzzer for inet_aton

---
 libc/fuzzing/CMakeLists.txt                   |  1 +
 libc/fuzzing/arpa/CMakeLists.txt              |  1 +
 libc/fuzzing/arpa/inet/CMakeLists.txt         |  7 +++
 .../arpa/inet/inet_aton_differential_fuzz.cpp | 46 +++++++++++++++++++
 4 files changed, 55 insertions(+)
 create mode 100644 libc/fuzzing/arpa/CMakeLists.txt
 create mode 100644 libc/fuzzing/arpa/inet/CMakeLists.txt
 create mode 100644 libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp

diff --git a/libc/fuzzing/CMakeLists.txt b/libc/fuzzing/CMakeLists.txt
index e2dcecca7f7df..de3ae527b495a 100644
--- a/libc/fuzzing/CMakeLists.txt
+++ b/libc/fuzzing/CMakeLists.txt
@@ -2,6 +2,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
 add_custom_target(libc-fuzzer)
 
 add_subdirectory(__support)
+add_subdirectory(arpa)
 # TODO(#85680): Re-enable math fuzzing after headers are sorted out
 add_subdirectory(math)
 add_subdirectory(stdlib)
diff --git a/libc/fuzzing/arpa/CMakeLists.txt b/libc/fuzzing/arpa/CMakeLists.txt
new file mode 100644
index 0000000000000..5c89828860ff8
--- /dev/null
+++ b/libc/fuzzing/arpa/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(inet)
diff --git a/libc/fuzzing/arpa/inet/CMakeLists.txt b/libc/fuzzing/arpa/inet/CMakeLists.txt
new file mode 100644
index 0000000000000..a2083133682ff
--- /dev/null
+++ b/libc/fuzzing/arpa/inet/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_libc_fuzzer(
+  inet_aton_differential_fuzz
+  SRCS
+    inet_aton_differential_fuzz.cpp
+  DEPENDS
+    libc.src.arpa.inet.inet_aton
+)
diff --git a/libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp b/libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp
new file mode 100644
index 0000000000000..e202f96c4c120
--- /dev/null
+++ b/libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Differential fuzz test for llvm-libc inet_aton implementation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/arpa/inet/inet_aton.h"
+#include <arpa/inet.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  if (size == 0 || data[size - 1] != '\0')
+    return -1;
+
+  struct in_addr ref_addr = {};
+  struct in_addr impl_addr = {};
+  int ref = ::inet_aton(reinterpret_cast<const char *>(data), &ref_addr);
+  int impl = LIBC_NAMESPACE::inet_aton(reinterpret_cast<const char *>(data),
+                                       &impl_addr);
+
+  if (ref != impl) {
+    fprintf(stderr,
+            "Different result (reference: %d, implementation: %d) for \"%s\"\n",
+            ref, impl, data);
+    __builtin_trap();
+  }
+
+  if (ref == 1 && ref_addr.s_addr != impl_addr.s_addr) {
+    fprintf(
+        stderr,
+        "Different address (reference: %x, implementation: %x) for \"%s\"\n",
+        ref_addr.s_addr, impl_addr.s_addr, data);
+    __builtin_trap();
+  }
+
+  return 0;
+}

>From c9a9b74277679bf550357a7afc8e3c6bf26a9fd7 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Fri, 29 May 2026 12:12:06 +0000
Subject: [PATCH 2/2] Copy input into temp buffer, resolve (some?) review
 comments

---
 libc/fuzzing/arpa/inet/CMakeLists.txt          |  2 ++
 .../arpa/inet/inet_aton_differential_fuzz.cpp  | 18 +++++++++++-------
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/libc/fuzzing/arpa/inet/CMakeLists.txt b/libc/fuzzing/arpa/inet/CMakeLists.txt
index a2083133682ff..0a940799c448d 100644
--- a/libc/fuzzing/arpa/inet/CMakeLists.txt
+++ b/libc/fuzzing/arpa/inet/CMakeLists.txt
@@ -3,5 +3,7 @@ add_libc_fuzzer(
   SRCS
     inet_aton_differential_fuzz.cpp
   DEPENDS
+    libc.src.__support.CPP.scope
     libc.src.arpa.inet.inet_aton
+    libc.src.string.memcpy
 )
diff --git a/libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp b/libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp
index e202f96c4c120..9b5006756059e 100644
--- a/libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp
+++ b/libc/fuzzing/arpa/inet/inet_aton_differential_fuzz.cpp
@@ -11,26 +11,30 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "src/__support/CPP/scope.h"
 #include "src/arpa/inet/inet_aton.h"
+#include "src/string/memcpy.h"
 #include <arpa/inet.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
-  if (size == 0 || data[size - 1] != '\0')
-    return -1;
+  // Create a null-terminated copy of the data
+  char *str = new char[size + 1];
+  LIBC_NAMESPACE::cpp::scope_exit delete_str([&] { delete[] str; });
+  LIBC_NAMESPACE::memcpy(str, data, size);
+  str[size] = '\0';
 
   struct in_addr ref_addr = {};
   struct in_addr impl_addr = {};
-  int ref = ::inet_aton(reinterpret_cast<const char *>(data), &ref_addr);
-  int impl = LIBC_NAMESPACE::inet_aton(reinterpret_cast<const char *>(data),
-                                       &impl_addr);
+  int ref = ::inet_aton(str, &ref_addr);
+  int impl = LIBC_NAMESPACE::inet_aton(str, &impl_addr);
 
   if (ref != impl) {
     fprintf(stderr,
             "Different result (reference: %d, implementation: %d) for \"%s\"\n",
-            ref, impl, data);
+            ref, impl, str);
     __builtin_trap();
   }
 
@@ -38,7 +42,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
     fprintf(
         stderr,
         "Different address (reference: %x, implementation: %x) for \"%s\"\n",
-        ref_addr.s_addr, impl_addr.s_addr, data);
+        ref_addr.s_addr, impl_addr.s_addr, str);
     __builtin_trap();
   }
 



More information about the libc-commits mailing list