summaryrefslogtreecommitdiff
path: root/Meta/Lagom/Fuzzers
diff options
context:
space:
mode:
Diffstat (limited to 'Meta/Lagom/Fuzzers')
-rw-r--r--Meta/Lagom/Fuzzers/CMakeLists.txt1
-rw-r--r--Meta/Lagom/Fuzzers/FuzzLzmaDecompression.cpp36
2 files changed, 37 insertions, 0 deletions
diff --git a/Meta/Lagom/Fuzzers/CMakeLists.txt b/Meta/Lagom/Fuzzers/CMakeLists.txt
index 8901747dfd..247d9f6442 100644
--- a/Meta/Lagom/Fuzzers/CMakeLists.txt
+++ b/Meta/Lagom/Fuzzers/CMakeLists.txt
@@ -35,6 +35,7 @@ add_simple_fuzzer(FuzzGzipDecompression LibCompress)
add_simple_fuzzer(FuzzICCProfile LibGfx)
add_simple_fuzzer(FuzzICOLoader LibGfx)
add_simple_fuzzer(FuzzJPEGLoader LibGfx)
+add_simple_fuzzer(FuzzLzmaDecompression LibArchive LibCompress)
add_simple_fuzzer(FuzzMatroskaReader LibVideo)
add_simple_fuzzer(FuzzMD5 LibCrypto)
add_simple_fuzzer(FuzzMP3Loader LibAudio)
diff --git a/Meta/Lagom/Fuzzers/FuzzLzmaDecompression.cpp b/Meta/Lagom/Fuzzers/FuzzLzmaDecompression.cpp
new file mode 100644
index 0000000000..fac0903162
--- /dev/null
+++ b/Meta/Lagom/Fuzzers/FuzzLzmaDecompression.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023, Tim Schumacher <timschumi@gmx.de>.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/MemoryStream.h>
+#include <LibCompress/Lzma.h>
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
+{
+ // LibFuzzer has a default memory limit of 2048 MB, so limit the dictionary size to a
+ // reasonable number to make sure that we don't actually run into it by allocating a
+ // huge dictionary. The chosen value is double of what the largest dictionary in the
+ // specifications test files is, so it should be more than enough for fuzzing everything
+ // that we would want to fuzz.
+ constexpr size_t largest_reasonable_dictionary_size = 16 * MiB;
+
+ if (size >= sizeof(Compress::LzmaHeader)) {
+ auto const* header = reinterpret_cast<Compress::LzmaHeader const*>(data);
+ if (header->dictionary_size() > largest_reasonable_dictionary_size)
+ return -1;
+ }
+
+ auto stream = make<FixedMemoryStream>(ReadonlyBytes { data, size });
+ auto decompressor_or_error = Compress::LzmaDecompressor::create_from_container(move(stream));
+ if (decompressor_or_error.is_error())
+ return 0;
+ auto decompressor = decompressor_or_error.release_value();
+ while (!decompressor->is_eof()) {
+ auto maybe_error = decompressor->discard(4096);
+ if (maybe_error.is_error())
+ break;
+ }
+ return 0;
+}