From 1ee93ac0991d5150ed5b21624e691da43b349612 Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Thu, 11 Jan 2024 11:06:46 +0100 Subject: [PATCH] [libc] Add memcmp / bcmp fuzzers (#77741) --- libc/fuzzing/string/CMakeLists.txt | 16 +++++ libc/fuzzing/string/bcmp_fuzz.cpp | 54 ++++++++++++++++ libc/fuzzing/string/memcmp_fuzz.cpp | 59 ++++++++++++++++++ ...h-f7dbdb2b330aad91f520099159e736e91bb9ddbf | Bin 0 -> 67 bytes 4 files changed, 129 insertions(+) create mode 100644 libc/fuzzing/string/bcmp_fuzz.cpp create mode 100644 libc/fuzzing/string/memcmp_fuzz.cpp create mode 100644 utils/bazel/crash-f7dbdb2b330aad91f520099159e736e91bb9ddbf diff --git a/libc/fuzzing/string/CMakeLists.txt b/libc/fuzzing/string/CMakeLists.txt index 1885ee5f66eb..9dd4fceee3b5 100644 --- a/libc/fuzzing/string/CMakeLists.txt +++ b/libc/fuzzing/string/CMakeLists.txt @@ -24,3 +24,19 @@ add_libc_fuzzer( libc.src.string.strstr libc.src.string.strlen ) + +add_libc_fuzzer( + memcmp_fuzz + SRCS + memcmp_fuzz.cpp + DEPENDS + libc.src.string.memcmp +) + +add_libc_fuzzer( + bcmp_fuzz + SRCS + bcmp_fuzz.cpp + DEPENDS + libc.src.string.bcmp +) diff --git a/libc/fuzzing/string/bcmp_fuzz.cpp b/libc/fuzzing/string/bcmp_fuzz.cpp new file mode 100644 index 000000000000..65949dfdf0c5 --- /dev/null +++ b/libc/fuzzing/string/bcmp_fuzz.cpp @@ -0,0 +1,54 @@ +//===-- bcmp_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 bcmp implementation. +/// +//===----------------------------------------------------------------------===// +#include "src/string/bcmp.h" +#include +#include +#include +#include + +static int reference_bcmp(const void *pa, const void *pb, size_t count) + __attribute__((no_builtin)) { + const auto *a = reinterpret_cast(pa); + const auto *b = reinterpret_cast(pb); + for (size_t i = 0; i < count; ++i, ++a, ++b) + if (*a != *b) + return 1; + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + const auto normalize = [](int value) -> int { + if (value == 0) + return 0; + return 1; + }; + // We ignore the last byte is size is odd. + const auto count = size / 2; + const char *a = reinterpret_cast(data); + const char *b = reinterpret_cast(data) + count; + const int actual = LIBC_NAMESPACE::bcmp(a, b, count); + const int reference = reference_bcmp(a, b, count); + if (normalize(actual) == normalize(reference)) + return 0; + const auto print = [](const char *msg, const char *buffer, size_t size) { + printf("%s\"", msg); + for (size_t i = 0; i < size; ++i) + printf("\\x%02x", (uint8_t)buffer[i]); + printf("\"\n"); + }; + printf("count : %zu\n", count); + print("a : ", a, count); + print("b : ", b, count); + printf("expected : %d\n", reference); + printf("actual : %d\n", actual); + __builtin_trap(); +} diff --git a/libc/fuzzing/string/memcmp_fuzz.cpp b/libc/fuzzing/string/memcmp_fuzz.cpp new file mode 100644 index 000000000000..879c21442287 --- /dev/null +++ b/libc/fuzzing/string/memcmp_fuzz.cpp @@ -0,0 +1,59 @@ +//===-- memcmp_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 memcmp implementation. +/// +//===----------------------------------------------------------------------===// +#include "src/string/memcmp.h" +#include +#include +#include +#include + +static int reference_memcmp(const void *pa, const void *pb, size_t count) + __attribute__((no_builtin)) { + const auto *a = reinterpret_cast(pa); + const auto *b = reinterpret_cast(pb); + for (size_t i = 0; i < count; ++i, ++a, ++b) { + if (*a < *b) + return -1; + else if (*a > *b) + return 1; + } + return 0; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + const auto sign = [](int value) -> int { + if (value < 0) + return -1; + if (value > 0) + return 1; + return 0; + }; + // We ignore the last byte is size is odd. + const auto count = size / 2; + const char *a = reinterpret_cast(data); + const char *b = reinterpret_cast(data) + count; + const int actual = LIBC_NAMESPACE::memcmp(a, b, count); + const int reference = reference_memcmp(a, b, count); + if (sign(actual) == sign(reference)) + return 0; + const auto print = [](const char *msg, const char *buffer, size_t size) { + printf("%s\"", msg); + for (size_t i = 0; i < size; ++i) + printf("\\x%02x", (uint8_t)buffer[i]); + printf("\"\n"); + }; + printf("count : %zu\n", count); + print("a : ", a, count); + print("b : ", b, count); + printf("expected : %d\n", reference); + printf("actual : %d\n", actual); + __builtin_trap(); +} diff --git a/utils/bazel/crash-f7dbdb2b330aad91f520099159e736e91bb9ddbf b/utils/bazel/crash-f7dbdb2b330aad91f520099159e736e91bb9ddbf new file mode 100644 index 0000000000000000000000000000000000000000..5dd7dca5e358f48f0cc0fd92a530cc70cfea7189 GIT binary patch literal 67 ZcmZQzI0*&}K)?ke@B?P3v@=54UjQvc1_S^A literal 0 HcmV?d00001