Add a dedicated fuzzer for SVG files.

75 views
Skip to first unread message

Sontapää11 Jokulainen

unread,
Jun 30, 2025, 10:43:10 AMJun 30
to Chromium-dev
Hi!

I have tried to implement a fuzzer for svg files and I now have this code:

```
// svg_document_fuzzer.cc
#include "third_party/blink/renderer/core/xml/dom_parser.h"
#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_supported_type.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/parser/html_construction_site.h"
#include "third_party/blink/renderer/core/keywords.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/core/xml/dom_parser.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"

// Not needed anymore ... #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" // Contains the stuff for DummyPageHolder

// These two next includes are for the v8 setup...

#include "v8/include/libplatform/libplatform.h"
#include "v8/include/v8.h"

extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
  static blink::BlinkFuzzerTestSupport test_support = blink::BlinkFuzzerTestSupport(); // Create fuzzer test support here.
  // Taken from run_all_unittests.cc
  // mojo::core::Init(); // Not needed I think
  v8::V8::InitializeICUDefaultLocation(*argv[0]);
  v8::V8::InitializeExternalStartupData(*argv[0]);
  auto platform = v8::platform::NewDefaultPlatform();
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();
  return 0; // Return success...
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  // These next two things do not work for some reason.
  // static base::test::SingleThreadTaskEnvironment task_environment;
  // base::test::TaskEnvironment task_environment;
  String svg_input = String::FromUTF8WithLatin1Fallback(UNSAFE_BUFFERS({data, size}));
  blink::V8TestingScope scope;
  auto* parser = blink::DOMParser::Create(scope.GetScriptState());
  parser->parseFromString(svg_input, blink::V8SupportedType(blink::V8SupportedType::Enum::kImageSvgXml)); // Load svg image...
  return 0;
}

```

and I added it to the `BUILD.gn` file as follows:

```
# Fuzzer for SVG document parsing
fuzzer_test("svg_document_fuzzer") {
  sources = [ "svg/svg_document_fuzzer.cc" ]
  deps = [
    ":core",
    "//third_party/blink/renderer/platform:platform",
    "//third_party/blink/renderer/platform:blink_fuzzer_test_support",
    "//third_party/blink/renderer/controller:blink_bindings_test_sources",
    "../platform:blink_fuzzer_test_support",
  ]
  dict = "//third_party/blink/renderer/core/svg/svg.dict"
  seed_corpus = "//third_party/blink/renderer/core/svg/svg_document_corpus"
}
```

and my command line looks like this:

```
#!/bin/sh

# We also need to use clang_use_chrome_plugins to disable the pointer error
gn gen out/svgfuzz \
  --args='is_debug=false use_libfuzzer=true is_asan=true symbol_level=1 use_dawn=false clang_use_chrome_plugins=false skia_use_dawn=false build_dawn_tests=false'
# Compile
autoninja -C out/svgfuzz svg_document_fuzzer
```

I am getting this error:

```
oof@oof-h8-1440eo:~/chromiumstuff/source/src/out/svgfuzz$ gdb --args ./svg_document_fuzzer corp/
r
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./svg_document_fuzzer...
(gdb) r
Starting program: /home/oof/chromiumstuff/source/src/out/svgfuzz/svg_document_fuzzer corp/
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Detected presence of a debugger, running without test timeouts.
[New Thread 0x7bffcc4be640 (LWP 58808)]
[New Thread 0x7bffcbcbd640 (LWP 58809)]
[New Thread 0x7bffca9b3640 (LWP 58810)]
[New Thread 0x7bffc96a9640 (LWP 58811)]
[New Thread 0x7bffc839f640 (LWP 58812)]
[New Thread 0x7bffc7095640 (LWP 58813)]
[New Thread 0x7bffc5d8b640 (LWP 58814)]


#
# Fatal error in ../../v8/src/init/v8.cc, line 85
# Wrong initialization order: from 4 to 5, expected to 1!
#
#
#
#FailureMessage Object: 0x7bfff0fd2c60#0 0x555572c69826 <unknown>
#1 0x555592cbaf76 <unknown>
#2 0x555592c6955f <unknown>
#3 0x555599e94f5f <unknown>
#4 0x555599c8f401 <unknown>
#5 0x55557b561f3b <unknown>
#6 0x55557b561d8b <unknown>
#7 0x555572cfd863 <unknown>
#8 0x5555732ea18f <unknown>
#9 0x5555732d4926 <unknown>
#10 0x7ffff3bd3d90 <unknown>
#11 0x7ffff3bd3e40 <unknown>
#12 0x555572c2202a <unknown>

Thread 1 "svg_document_fu" received signal SIGTRAP, Trace/breakpoint trap.
0x0000555599ccb533 in operator() () at ../../v8/src/base/platform/platform-posix.cc:766
766       IMMEDIATE_CRASH();
(gdb) where
#0  0x0000555599ccb533 in operator() () at ../../v8/src/base/platform/platform-posix.cc:766
#1  Abort() () at ../../v8/src/base/platform/platform-posix.cc:766
#2  0x0000555599c8f425 in V8_Fatal() () at ../../v8/src/base/logging.cc:215
#3  0x000055557b561f3b in AdvanceStartupState() () at ../../v8/src/init/v8.cc:83
#4  0x000055557b561d8b in v8::internal::V8::InitializePlatform(v8::Platform*) () at ../../v8/src/init/v8.cc:104
#5  0x0000555572cfd863 in LLVMFuzzerInitialize() ()
    at ../../third_party/blink/renderer/core/svg/svg_document_fuzzer.cc:39
#6  0x00005555732ea18f in FuzzerDriver() () at ../../third_party/libFuzzer/src/FuzzerDriver.cpp:651
#7  0x00005555732d4926 in main () at ../../third_party/libFuzzer/src/FuzzerMain.cpp:20
(gdb) 
```

but if I comment out the test_support line here:

```
// svg_document_fuzzer.cc
#include "third_party/blink/renderer/core/xml/dom_parser.h"
#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_supported_type.h"
#include "third_party/blink/renderer/core/dom/document_fragment.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_div_element.h"
#include "third_party/blink/renderer/core/html/html_document.h"
#include "third_party/blink/renderer/core/html/parser/html_construction_site.h"
#include "third_party/blink/renderer/core/keywords.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/testing/null_execution_context.h"
#include "third_party/blink/renderer/core/xml/dom_parser.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"

// Not needed anymore ... #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" // Contains the stuff for DummyPageHolder

// These two next includes are for the v8 setup...

#include "v8/include/libplatform/libplatform.h"
#include "v8/include/v8.h"

extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
  // static blink::BlinkFuzzerTestSupport test_support = blink::BlinkFuzzerTestSupport(); // Create fuzzer test support here.
  // Taken from run_all_unittests.cc
  // mojo::core::Init(); // Not needed I think
  v8::V8::InitializeICUDefaultLocation(*argv[0]);
  v8::V8::InitializeExternalStartupData(*argv[0]);
  auto platform = v8::platform::NewDefaultPlatform();
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();
  return 0; // Return success...
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  // These next two things do not work for some reason.
  // static base::test::SingleThreadTaskEnvironment task_environment;
  // base::test::TaskEnvironment task_environment;
  String svg_input = String::FromUTF8WithLatin1Fallback(UNSAFE_BUFFERS({data, size}));
  blink::V8TestingScope scope;
  auto* parser = blink::DOMParser::Create(scope.GetScriptState());
  parser->parseFromString(svg_input, blink::V8SupportedType(blink::V8SupportedType::Enum::kImageSvgXml)); // Load svg image...
  return 0;
}
```

I am getting this output:

```
oof@oof-h8-1440eo:~/chromiumstuff/source/src/out/svgfuzz$ gdb --args ./svg_document_fuzzer corp/
r
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./svg_document_fuzzer...
(gdb) r
Starting program: /home/oof/chromiumstuff/source/src/out/svgfuzz/svg_document_fuzzer corp/
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7bffee151640 (LWP 56513)]
[New Thread 0x7bffed950640 (LWP 56514)]
[New Thread 0x7bffed14f640 (LWP 56515)]
[New Thread 0x7bffebe45640 (LWP 56516)]
[New Thread 0x7bffea024640 (LWP 56517)]
[New Thread 0x7bffe8d0c640 (LWP 56518)]
[New Thread 0x7bffe79f4640 (LWP 56519)]
[Thread 0x7bffe79f4640 (LWP 56519) exited]
[Thread 0x7bffe8d0c640 (LWP 56518) exited]
[Thread 0x7bffea024640 (LWP 56517) exited]
[Thread 0x7bffebe45640 (LWP 56516) exited]
[Thread 0x7bffed14f640 (LWP 56515) exited]
[Thread 0x7bffed950640 (LWP 56514) exited]
[Thread 0x7bffee151640 (LWP 56513) exited]
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 4022611497
INFO: Loaded 2 modules   (8892795 inline 8-bit counters): 292214 [0x7ffff7ad55a0, 0x7ffff7b1cb16), 8600581 [0x5555ad56d500, 0x5555adda1105),
INFO: Loaded 2 PC tables (8892795 PCs): 292214 [0x7ffff7b1cb18,0x7ffff7f92278), 8600581 [0x5555adda1108,0x5555b60dd158),
[New Thread 0x7bffee151640 (LWP 56520)]
INFO:     2404 files found in corp/
INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 919486 bytes
[0630/020442.816434:FATAL:third_party/blink/renderer/platform/wtf/allocator/partitions.h:106] DCHECK failed: initialized_.

Thread 1 "svg_document_fu" received signal SIGABRT, Aborted.
__pthread_kill_implementation (no_tid=0, signo=6, threadid=140737265644096) at ./nptl/pthread_kill.c:44
44 ./nptl/pthread_kill.c: No such file or directory.
(gdb) where
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737265644096) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=140737265644096) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=140737265644096, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007ffff3bec476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007ffff3bd27f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x0000555592887402 in ImmediateCrash () at ../../base/immediate_crash.h:191
#6  HandleFatal() () at ../../base/logging.cc:1073
#7  0x0000555592886469 in operator() () at ../../base/logging.cc:769
#8  InvokeCallback () at ../../third_party/abseil-cpp/absl/cleanup/internal/cleanup.h:86
#9  ~Cleanup () at ../../third_party/abseil-cpp/absl/cleanup/cleanup.h:106
#10 Flush() () at ../../base/logging.cc:952
#11 0x00005555928851de in ~LogMessage() () at ../../base/logging.cc:722
#12 0x00005555928378de in ~DCheckLogMessage () at ../../base/check.cc:176
#13 ~DCheckLogMessage() () at ../../base/check.cc:172
#14 0x000055559283630e in operator() () at ../../third_party/libc++/src/include/__memory/unique_ptr.h:77
#15 reset () at ../../third_party/libc++/src/include/__memory/unique_ptr.h:290
#16 ~CheckError() () at ../../base/check.cc:335
#17 0x0000555599b6a0da in FastMallocPartition ()
    at ../../third_party/blink/renderer/platform/wtf/allocator/partitions.h:106
#18 FastMalloc() () at ../../third_party/blink/renderer/platform/wtf/allocator/partitions.cc:361
#19 0x00005555899c3dba in operator new () at ../../third_party/blink/renderer/core/testing/dummy_page_holder.h:70
#20 make_unique<blink::DummyPageHolder, const gfx::Size &, blink::ChromeClient *&, blink::LocalFrameClient *&, base::OnceCallback<void (blink::Settings &)>, const base::TickClock *&, 0> ()
    at ../../third_party/libc++/src/include/__memory/unique_ptr.h:759
#21 CreateAndCommitNavigation() () at ../../third_party/blink/renderer/core/testing/dummy_page_holder.cc:78
#22 0x000055557319240d in V8TestingScope() ()
    at ../../third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc:18
--Type <RET> for more, q to quit, c to continue without paging--
#23 0x0000555572cfdb2b in LLVMFuzzerTestOneInput() ()
    at ../../third_party/blink/renderer/core/svg/svg_document_fuzzer.cc:49
#24 0x0000555573310ecd in ExecuteCallback() () at ../../third_party/libFuzzer/src/FuzzerLoop.cpp:619
#25 0x0000555573313b9e in ReadAndExecuteSeedCorpora() () at ../../third_party/libFuzzer/src/FuzzerLoop.cpp:812
#26 0x0000555573314901 in Loop() () at ../../third_party/libFuzzer/src/FuzzerLoop.cpp:872
#27 0x00005555732ecb45 in FuzzerDriver() () at ../../third_party/libFuzzer/src/FuzzerDriver.cpp:915
#28 0x00005555732d4316 in main () at ../../third_party/libFuzzer/src/FuzzerMain.cpp:20
(gdb) 
```


I have struggled with this for a couple of days now and I am getting quite desperate. It seems that no matter what I do, I always get some error in the initialization code. My question is, how do I actually properly set up the environment (like V8) before calling V8TestingScope or other related functions and before calling the svg parser?

Thanks in advance for your response!




Reply all
Reply to author
Forward
0 new messages