From 96c3d4f440d9880dfb7c9aa9d6fe49959ff6124d Mon Sep 17 00:00:00 2001 From: Ravi Jotwani Date: Tue, 14 Jul 2020 14:01:37 -0700 Subject: [PATCH] [openexr] Replace buf_to_file with IStream (#4094) * Add a working skeleton for OpenEXR fuzzers. * added openexr fuzzers, updated build script to include them * cleaned up bash loop * [openexr] Replace buf_to_file with StdISStream. Version 2.5.0 of OpenEXR added a StdISStream class that turns a std::string into an Imf::IStream, which can be used instead of filenames when opening an OpenEXR image. This commit adds code which wraps the fuzzer input into a StdISStream, which enables us to remove the hacky buf_to_file function. * updated deepscanlines_fuzzer to use IStream instead of filenames * replace "/work" with in build.sh * Reformat CMake settings, and also prevent building utils and examples. * Reformat and change names in build.sh. * Omit the version prefix when building OpenEXR and IlmBase libraries. * updated final two fuzzers to use istream * fixed additional conflict in project.yaml * get header size from input * increased header size * Fix argument types in readFileSingle Co-authored-by: Michael Jezierny Co-authored-by: Abhishek Arya --- .../openexr/openexr_deepscanlines_fuzzer.cc | 54 ++++++++----------- projects/openexr/openexr_deeptiles_fuzzer.cc | 46 +++++----------- projects/openexr/openexr_scanlines_fuzzer.cc | 44 ++++----------- projects/openexr/openexr_tiles_fuzzer.cc | 44 ++++----------- 4 files changed, 56 insertions(+), 132 deletions(-) diff --git a/projects/openexr/openexr_deepscanlines_fuzzer.cc b/projects/openexr/openexr_deepscanlines_fuzzer.cc index 9682dea0f..ff77d8e45 100644 --- a/projects/openexr/openexr_deepscanlines_fuzzer.cc +++ b/projects/openexr/openexr_deepscanlines_fuzzer.cc @@ -24,6 +24,9 @@ #include #include #include +#include + +#include namespace IMF = OPENEXR_IMF_NAMESPACE; using namespace IMF; @@ -108,10 +111,11 @@ static void readFile(T *inpart) { } } -static void readFileSingle(const char filename[]) { +static void readFileSingle(IStream& is, uint64_t width, uint64_t height) { DeepScanLineInputFile *file = NULL; + Header header(width, height); try { - file = new DeepScanLineInputFile(filename, 0); + file = new DeepScanLineInputFile(header, &is, EXR_VERSION, 0); } catch (...) { return; } @@ -124,10 +128,10 @@ static void readFileSingle(const char filename[]) { delete file; } -static void readFileMulti(const char filename[]) { +static void readFileMulti(IStream& is) { MultiPartInputFile *file = NULL; try { - file = new MultiPartInputFile(filename, 0); + file = new MultiPartInputFile(is, 0); } catch (...) { return; } @@ -151,35 +155,19 @@ static void readFileMulti(const char filename[]) { } // namespace -// from cl/164883104 -static char *buf_to_file(const char *buf, size_t size) { - char *name = strdup("/dev/shm/fuzz-XXXXXX"); - int fd = mkstemp(name); - if (fd < 0) { - perror("open"); - exit(1); - } - size_t pos = 0; - while (pos < size) { - int nbytes = write(fd, &buf[pos], size - pos); - if (nbytes <= 0) { - perror("write"); - exit(1); - } - pos += nbytes; - } - if (close(fd) != 0) { - perror("close"); - exit(1); - } - return name; -} - extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - char *file = buf_to_file((const char *)data, size); - readFileSingle(file); - readFileMulti(file); - unlink(file); - free(file); + if (size < 16) return 0; + + FuzzedDataProvider stream(data, size); + uint64_t width = stream.ConsumeIntegral(); + uint64_t height = stream.ConsumeIntegral(); + std::vector buffer = stream.ConsumeRemainingBytes(); + + const std::string s(buffer.data(), buffer.size()); + StdISStream is; + is.str(s); + + readFileSingle(is, width, height); + readFileMulti(is); return 0; } diff --git a/projects/openexr/openexr_deeptiles_fuzzer.cc b/projects/openexr/openexr_deeptiles_fuzzer.cc index 4a51be115..b4f0e056f 100644 --- a/projects/openexr/openexr_deeptiles_fuzzer.cc +++ b/projects/openexr/openexr_deeptiles_fuzzer.cc @@ -23,6 +23,7 @@ #include #include #include +#include namespace IMF = OPENEXR_IMF_NAMESPACE; using namespace IMF; @@ -115,10 +116,10 @@ static void readFile(T *part) { } } -static void readFileSingle(const char filename[]) { +static void readFileSingle(IStream& is) { DeepTiledInputFile *file; try { - file = new DeepTiledInputFile(filename, 8); + file = new DeepTiledInputFile(is, 8); } catch (...) { return; } @@ -131,11 +132,11 @@ static void readFileSingle(const char filename[]) { delete file; } -static void readFileMulti(const char filename[]) { +static void readFileMulti(IStream& is) { MultiPartInputFile *file; try { - file = new MultiPartInputFile(filename, 8); + file = new MultiPartInputFile(is, 8); } catch (...) { return; } @@ -161,36 +162,15 @@ static void readFileMulti(const char filename[]) { } // namespace -// from cl/164883104 -static char *buf_to_file(const char *buf, size_t size) { - char *name = strdup("/dev/shm/fuzz-XXXXXX"); - int fd = mkstemp(name); - if (fd < 0) { - perror("open"); - exit(1); - } - size_t pos = 0; - while (pos < size) { - int nbytes = write(fd, &buf[pos], size - pos); - if (nbytes <= 0) { - perror("write"); - exit(1); - } - pos += nbytes; - } - if (close(fd) != 0) { - perror("close"); - exit(1); - } - return name; -} - extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - char *file = buf_to_file((const char *)data, size); + + const std::string s(reinterpret_cast(data), size); + StdISStream is; + is.str(s); + Header::setMaxImageSize(10000, 10000); - readFileSingle(file); - readFileMulti(file); - unlink(file); - free(file); + readFileSingle(is); + readFileMulti(is); + return 0; } diff --git a/projects/openexr/openexr_scanlines_fuzzer.cc b/projects/openexr/openexr_scanlines_fuzzer.cc index 214b595d8..26623a1fc 100644 --- a/projects/openexr/openexr_scanlines_fuzzer.cc +++ b/projects/openexr/openexr_scanlines_fuzzer.cc @@ -22,16 +22,17 @@ #include #include #include +#include using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; using IMATH_NAMESPACE::Box2i; namespace { -static void readSingle(const char fileName[]) { +static void readSingle(IStream& is) { RgbaInputFile *in = NULL; try { - in = new RgbaInputFile(fileName); + in = new RgbaInputFile(is); } catch (...) { return; } @@ -54,10 +55,10 @@ static void readSingle(const char fileName[]) { delete in; } -static void readMulti(const char fileName[]) { +static void readMulti(IStream& is) { MultiPartInputFile *file; try { - file = new MultiPartInputFile(fileName); + file = new MultiPartInputFile(is); } catch (...) { return; } @@ -98,35 +99,12 @@ static void readMulti(const char fileName[]) { } // namespace -// from cl/164883104 -static char *buf_to_file(const char *buf, size_t size) { - char *name = strdup("/dev/shm/fuzz-XXXXXX"); - int fd = mkstemp(name); - if (fd < 0) { - perror("open"); - exit(1); - } - size_t pos = 0; - while (pos < size) { - int nbytes = write(fd, &buf[pos], size - pos); - if (nbytes <= 0) { - perror("write"); - exit(1); - } - pos += nbytes; - } - if (close(fd) != 0) { - perror("close"); - exit(1); - } - return name; -} - extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - char *file = buf_to_file((const char *)data, size); - readSingle(file); - readMulti(file); - unlink(file); - free(file); + const std::string s(reinterpret_cast(data), size); + StdISStream is; + is.str(s); + + readSingle(is); + readMulti(is); return 0; } diff --git a/projects/openexr/openexr_tiles_fuzzer.cc b/projects/openexr/openexr_tiles_fuzzer.cc index 2cc8ccd7a..d473021ce 100644 --- a/projects/openexr/openexr_tiles_fuzzer.cc +++ b/projects/openexr/openexr_tiles_fuzzer.cc @@ -29,6 +29,7 @@ #include #include #include +#include using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; using IMATH_NAMESPACE::Box2i; @@ -49,10 +50,10 @@ void readImageONE(TiledRgbaInputFile *in, int dwx, int dwy) { } } -void readImageONE2(const char fileName[]) { +void readImageONE2(IStream& is) { MultiPartInputFile *in; try { - in = new MultiPartInputFile(fileName); + in = new MultiPartInputFile(is); } catch (...) { return; } @@ -140,13 +141,13 @@ void readImageRIP(TiledRgbaInputFile *in, int dwx, int dwy) { } // namespace -static void fuzzImage(const char filename[]) { +static void fuzzImage(IStream& is) { Header::setMaxImageSize(10000, 10000); Header::setMaxTileSize(10000, 10000); TiledRgbaInputFile *in; try { - in = new TiledRgbaInputFile(filename); + in = new TiledRgbaInputFile(is); } catch (...) { return; } @@ -158,39 +159,16 @@ static void fuzzImage(const char filename[]) { readImageMIP(in, dwx, dwy); readImageRIP(in, dwx, dwy); readImageONE(in, dwx, dwy); - readImageONE2(filename); + readImageONE2(is); delete in; } -// from cl/164883104 -static char *buf_to_file(const char *buf, size_t size) { - char *name = strdup("/dev/shm/fuzz-XXXXXX"); - int fd = mkstemp(name); - if (fd < 0) { - perror("open"); - exit(1); - } - size_t pos = 0; - while (pos < size) { - int nbytes = write(fd, &buf[pos], size - pos); - if (nbytes <= 0) { - perror("write"); - exit(1); - } - pos += nbytes; - } - if (close(fd) != 0) { - perror("close"); - exit(1); - } - return name; -} - extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - char *file = buf_to_file((const char *)data, size); - fuzzImage(file); - unlink(file); - free(file); + const std::string s(reinterpret_cast(data), size); + StdISStream is; + is.str(s); + + fuzzImage(is); return 0; }