For issues not further understood, GCC 14, but not clang 19,
UndefinedBehaviorSanitizer doesn't like the way we iterate over the
linker list that holds the fuzzers:

  barebox@Sandbox:/ fuzz -l
  dtb
  commands/fuzz.c:19:23: runtime error: load of address 0x560e1830a050 with
  insufficient space for an object of type 'const struct fuzz_test'
  0x560e1830a050: note: pointer points here
   0e 56 00 00  e0 77 26 18 0e 56 00 00  ef e2 0f 18 0e 56 00 00
                ^
   20 44 25 18 0e 56 00 00  1f be 09 18
  fdt-compatible
  filetype
  fit
  partitions

For some reason, switching to call_for_each_fuzz_test, avoids this
issue, so let's do that.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 commands/fuzz.c | 42 ++++++++++++++++++++++++++++++------------
 include/fuzz.h  |  4 ----
 lib/fuzz.c      |  4 ++++
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/commands/fuzz.c b/commands/fuzz.c
index f48032e7e1d9..3ade5bf69a28 100644
--- a/commands/fuzz.c
+++ b/commands/fuzz.c
@@ -9,23 +9,41 @@
 #include <libfile.h>
 #include <fs.h>
 
-static const struct fuzz_test *get_fuzz_test(const char *match, bool print)
-{
+struct fuzz_process {
+       bool print;
+       const char *match;
+       unsigned nmatches;
        const struct fuzz_test *test;
-       unsigned matches = 0;
+};
 
-       for_each_fuzz_test(test) {
-               if (print) {
-                       printf("%s\n", test->name);
-                       matches++;
-               }
-
-               if (match && !strcmp(test->name, match))
-                       return test;
+static int process_fuzz_test(const struct fuzz_test *test,
+                            void *_ctx)
+{
+       struct fuzz_process *ctx = _ctx;
 
+       if (ctx->print) {
+               printf("%s\n", test->name);
+               ctx->nmatches++;
        }
 
-       if (!matches) {
+       if (ctx->match && !strcmp(test->name, ctx->match)) {
+               ctx->test = test;
+               return true;
+       }
+
+       return false;
+}
+
+static const struct fuzz_test *get_fuzz_test(const char *match, bool print)
+{
+       struct fuzz_process ctx = {
+               .match = match, .print = print
+       };
+
+       if (call_for_each_fuzz_test(process_fuzz_test, &ctx))
+               return ctx.test;
+
+       if (!ctx.nmatches) {
                if (match)
                        printf("No fuzz tests matching '%s' found.\n", match);
                else
diff --git a/include/fuzz.h b/include/fuzz.h
index 11332e834753..4d637f72b176 100644
--- a/include/fuzz.h
+++ b/include/fuzz.h
@@ -27,10 +27,6 @@ struct fuzz_test {
 extern const struct fuzz_test __barebox_fuzz_tests_start;
 extern const struct fuzz_test __barebox_fuzz_tests_end;
 
-#define for_each_fuzz_test(test) \
-       for (test = &__barebox_fuzz_tests_start; \
-            test != &__barebox_fuzz_tests_end; test++)
-
 #if IS_ENABLED(CONFIG_FUZZ) && IN_PROPER
 /**
  * fuzz_test() - register a fuzz test
diff --git a/lib/fuzz.c b/lib/fuzz.c
index 038e176096bc..708cffbc2cc5 100644
--- a/lib/fuzz.c
+++ b/lib/fuzz.c
@@ -4,6 +4,10 @@
 #include <string.h>
 #include <common.h>
 
+#define for_each_fuzz_test(test) \
+       for (test = &__barebox_fuzz_tests_start; \
+            test != &__barebox_fuzz_tests_end; test++)
+
 int call_for_each_fuzz_test(int (*fn)(const struct fuzz_test *test, void *ctx),
                            void *ctx)
 {
-- 
2.47.3


Reply via email to