diff --git a/.bazelrc b/.bazelrc index e2f60eff9f58..5cabd87c0e54 100644 --- a/.bazelrc +++ b/.bazelrc @@ -4,6 +4,7 @@ common --extra_toolchains=@llvm_18_toolchain//:all common --@toolchains_llvm//toolchain/config:libunwind=False common --@toolchains_llvm//toolchain/config:compiler-rt=False build --linkopt --unwindlib=libgcc +build --linkopt -stdlib=libc++ common:clang-19 --extra_toolchains=@llvm_19_toolchain//:all @@ -47,6 +48,7 @@ build:sanitizer --linkopt -fsanitize=address,undefined,vptr,function build:sanitizer --linkopt --rtlib=compiler-rt build:sanitizer --linkopt -fsanitize-link-c++-runtime build:sanitizer --copt -O1 +build:sanitizer --//bazel:has_sanitizers=True # seastar has to be run with system allocator when using sanitizers build:sanitizer --@seastar//:system_allocator=True # krb5 is a foreign cc build and needs explicit list of sanitizers to build the shared library diff --git a/bazel/BUILD b/bazel/BUILD index e69de29bb2d1..9b4763c5e1b8 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -0,0 +1,13 @@ +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") + +bool_flag( + name = "has_sanitizers", + build_setting_default = False, +) + +config_setting( + name = "enable_fuzz_testing", + flag_values = { + ":has_sanitizers": "true", + }, +) diff --git a/bazel/test.bzl b/bazel/test.bzl index 7af017422c8b..99fa03cc2231 100644 --- a/bazel/test.bzl +++ b/bazel/test.bzl @@ -130,6 +130,53 @@ def _redpanda_cc_test( local_defines = local_defines, ) +def _redpanda_cc_fuzz_test( + name, + timeout, + srcs = [], + defines = [], + deps = [], + custom_args = [], + env = {}, + data = []): + """ + Helper to define a Redpanda C++ fuzzing test. + + Args: + name: name of the test + timeout: same as native cc_test + srcs: test source files + defines: definitions of object-like macros + deps: test dependencies + custom_args: arguments from cc_test users + env: environment variables + data: data file dependencies + """ + native.cc_test( + name = name, + timeout = timeout, + srcs = srcs, + defines = defines, + deps = deps, + copts = redpanda_copts(), + args = custom_args, + features = [ + "layering_check", + ], + tags = [ + "fuzz", + ], + env = env, + data = data, + linkopts = [ + "-fsanitize=fuzzer", + ], + target_compatible_with = select({ + "//bazel:enable_fuzz_testing": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + ) + def _redpanda_cc_unit_test(cpu, memory, **kwargs): extra_args = [ "--unsafe-bypass-fsync 1", @@ -231,6 +278,26 @@ def redpanda_cc_bench( ], ) +def redpanda_cc_fuzz_test( + name, + timeout, + srcs = [], + defines = [], + deps = [], + args = [], + env = {}, + data = []): + _redpanda_cc_fuzz_test( + data = data, + env = env, + name = name, + timeout = timeout, + srcs = srcs, + defines = defines, + deps = deps, + custom_args = args, + ) + def redpanda_cc_btest_no_seastar( name, timeout, diff --git a/src/v/bytes/tests/BUILD b/src/v/bytes/tests/BUILD index d4a3869cc5ff..80ade1d1558b 100644 --- a/src/v/bytes/tests/BUILD +++ b/src/v/bytes/tests/BUILD @@ -1,4 +1,4 @@ -load("//bazel:test.bzl", "redpanda_cc_btest", "redpanda_cc_gtest") +load("//bazel:test.bzl", "redpanda_cc_btest", "redpanda_cc_fuzz_test", "redpanda_cc_gtest") redpanda_cc_btest( name = "iobuf_test", @@ -76,3 +76,18 @@ redpanda_cc_btest( "@seastar//:testing", ], ) + +redpanda_cc_fuzz_test( + name = "iobuf_fuzz", + timeout = "short", + srcs = ["iobuf_fuzz.cc"], + args = [ + "-max_total_time=30", + "-rss_limit_mb=8192", + ], + deps = [ + "//src/v/base", + "//src/v/bytes:iobuf", + "//src/v/bytes:scattered_message", + ], +) diff --git a/src/v/bytes/tests/iobuf_fuzz.cc b/src/v/bytes/tests/iobuf_fuzz.cc index 6b9ccaa6ed01..0dd492495558 100644 --- a/src/v/bytes/tests/iobuf_fuzz.cc +++ b/src/v/bytes/tests/iobuf_fuzz.cc @@ -17,10 +17,10 @@ * -format=html ../src/v/bytes/iobuf.h ../src/v/bytes/iobuf.cc > cov.html */ #include "base/vassert.h" -#include "bytes/bytes.h" #include "bytes/iobuf.h" #include "bytes/scattered_message.h" +#include #include /* @@ -508,7 +508,7 @@ class driver { template T read() { - if (std::distance(pc_, program_.cend()) < sizeof(T)) { + if (std::cmp_less(std::distance(pc_, program_.cend()), sizeof(T))) { throw end_of_program(); } T ret;