From 75b0abefd8ead6954cadf8e5bab498f39f25c846 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Fri, 14 Jun 2019 11:08:36 -0700 Subject: [PATCH] vpx_dec_fuzzer: Remove fmemopen dependency fmemopen is not preferred during fuzzing. Removed all file operations. Removed need for allocating a different input buffer. data buffer is appropriately incremented and passed directly to decoder This will also test input being sent in an unaligned buffer to the library. Removed read_frame function and did the required parsing inline. Change-Id: I32829b0149dba9339f2e8bb4c0249a4987a630c7 --- examples/vpx_dec_fuzzer.cc | 71 +++++++------------------------------- 1 file changed, 13 insertions(+), 58 deletions(-) diff --git a/examples/vpx_dec_fuzzer.cc b/examples/vpx_dec_fuzzer.cc index ba5af9329..d55fe1571 100644 --- a/examples/vpx_dec_fuzzer.cc +++ b/examples/vpx_dec_fuzzer.cc @@ -66,6 +66,7 @@ #include #include #include +#include #include #include "vpx/vp8dx.h" @@ -78,61 +79,10 @@ #define VPXD_INTERFACE(name) VPXD_INTERFACE_(name) #define VPXD_INTERFACE_(name) vpx_codec_##name##_dx() -static void CloseFile(FILE *file) { fclose(file); } - -/* ReadFrame is derived from ivf_read_frame in ivfdec.c - * This function doesn't call warn(), but instead ignores those errors. - * This is done to minimize the prints on console when running fuzzer - * Also if fread fails to read frame_size number of bytes, instead of - * returning an error, this returns with partial frames. - * This is done to ensure that partial frames are sent to decoder. - */ -static int ReadFrame(FILE *infile, uint8_t **buffer, size_t *bytes_read, - size_t *buffer_size) { - char raw_header[IVF_FRAME_HDR_SZ] = { 0 }; - size_t frame_size = 0; - - if (fread(raw_header, IVF_FRAME_HDR_SZ, 1, infile) == 1) { - frame_size = mem_get_le32(raw_header); - - if (frame_size > 256 * 1024 * 1024) { - frame_size = 0; - } - - if (frame_size > *buffer_size) { - uint8_t *new_buffer = (uint8_t *)realloc(*buffer, 2 * frame_size); - - if (new_buffer) { - *buffer = new_buffer; - *buffer_size = 2 * frame_size; - } else { - frame_size = 0; - } - } - } - - if (!feof(infile)) { - *bytes_read = fread(*buffer, 1, frame_size, infile); - return 0; - } - - return 1; -} - extern "C" void usage_exit(void) { exit(EXIT_FAILURE); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - std::unique_ptr file( - fmemopen((void *)data, size, "rb"), &CloseFile); - if (file == nullptr) { - return 0; - } - // Ensure input contains at least one file header and one frame header - if (size < IVF_FILE_HDR_SZ + IVF_FRAME_HDR_SZ) { - return 0; - } - char header[IVF_FILE_HDR_SZ]; - if (fread(header, 1, IVF_FILE_HDR_SZ, file.get()) != IVF_FILE_HDR_SZ) { + if (size <= IVF_FILE_HDR_SZ) { return 0; } @@ -144,20 +94,25 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } - uint8_t *buffer = nullptr; - size_t buffer_size = 0; - size_t frame_size = 0; + data += IVF_FILE_HDR_SZ; + size -= IVF_FILE_HDR_SZ; + + while (size > IVF_FRAME_HDR_SZ) { + size_t frame_size = mem_get_le32(data); + size -= IVF_FRAME_HDR_SZ; + data += IVF_FRAME_HDR_SZ; + frame_size = std::min(size, frame_size); - while (!ReadFrame(file.get(), &buffer, &frame_size, &buffer_size)) { const vpx_codec_err_t err = - vpx_codec_decode(&codec, buffer, frame_size, nullptr, 0); + vpx_codec_decode(&codec, data, frame_size, nullptr, 0); static_cast(err); vpx_codec_iter_t iter = nullptr; vpx_image_t *img = nullptr; while ((img = vpx_codec_get_frame(&codec, &iter)) != nullptr) { } + data += frame_size; + size -= frame_size; } vpx_codec_destroy(&codec); - free(buffer); return 0; } -- 2.40.0