OSS-Fuzz: cjpeg fuzz target

This commit is contained in:
DRC
2021-04-09 17:26:19 -05:00
parent 5cda8c5e31
commit 4ede2ef523
4 changed files with 161 additions and 4 deletions

70
cjpeg.c
View File

@@ -5,7 +5,7 @@
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2003-2011 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2013-2014, 2017, 2019-2020, D. R. Commander.
* Copyright (C) 2010, 2013-2014, 2017, 2019-2021, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -27,6 +27,9 @@
* works regardless of which command line style is used.
*/
#ifdef CJPEG_FUZZER
#define JPEG_INTERNALS
#endif
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jversion.h" /* for version message */
#include "jconfigint.h"
@@ -146,6 +149,45 @@ boolean memdst; /* for -memdst switch */
boolean report; /* for -report switch */
#ifdef CJPEG_FUZZER
#include <setjmp.h>
struct my_error_mgr {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
void my_error_exit(j_common_ptr cinfo)
{
struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err;
longjmp(myerr->setjmp_buffer, 1);
}
static void my_emit_message(j_common_ptr cinfo, int msg_level)
{
if (msg_level < 0)
cinfo->err->num_warnings++;
}
#define HANDLE_ERROR() { \
if (cinfo.global_state > CSTATE_START) { \
if (memdst && outbuffer) \
(*cinfo.dest->term_destination) (&cinfo); \
jpeg_abort_compress(&cinfo); \
} \
jpeg_destroy_compress(&cinfo); \
if (input_file != stdin && input_file != NULL) \
fclose(input_file); \
if (memdst) \
free(outbuffer); \
return EXIT_FAILURE; \
}
#endif
LOCAL(void)
usage(void)
/* complain about bad command line */
@@ -506,11 +548,16 @@ int
main(int argc, char **argv)
{
struct jpeg_compress_struct cinfo;
#ifdef CJPEG_FUZZER
struct my_error_mgr myerr;
struct jpeg_error_mgr &jerr = myerr.pub;
#else
struct jpeg_error_mgr jerr;
#endif
struct cdjpeg_progress_mgr progress;
int file_index;
cjpeg_source_ptr src_mgr;
FILE *input_file;
FILE *input_file = NULL;
FILE *icc_file;
JOCTET *icc_profile = NULL;
long icc_len = 0;
@@ -628,6 +675,13 @@ main(int argc, char **argv)
fclose(icc_file);
}
#ifdef CJPEG_FUZZER
jerr.error_exit = my_error_exit;
jerr.emit_message = my_emit_message;
if (setjmp(myerr.setjmp_buffer))
HANDLE_ERROR()
#endif
if (report) {
start_progress_monitor((j_common_ptr)&cinfo, &progress);
progress.report = report;
@@ -654,6 +708,13 @@ main(int argc, char **argv)
#endif
jpeg_stdio_dest(&cinfo, output_file);
#ifdef CJPEG_FUZZER
if (cinfo.image_width < 1 || cinfo.image_height < 1 ||
(unsigned long long)cinfo.image_width * cinfo.image_height > 1048576 ||
setjmp(myerr.setjmp_buffer))
HANDLE_ERROR()
#endif
/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);
@@ -681,13 +742,14 @@ main(int argc, char **argv)
end_progress_monitor((j_common_ptr)&cinfo);
if (memdst) {
#ifndef CJPEG_FUZZER
fprintf(stderr, "Compressed size: %lu bytes\n", outsize);
#endif
free(outbuffer);
}
free(icc_profile);
/* All done. */
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */
return (jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
}

View File

@@ -25,6 +25,12 @@ set(EFFECTIVE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
message(STATUS "C++ Compiler flags = ${EFFECTIVE_CXX_FLAGS}")
add_executable(cjpeg_fuzzer cjpeg.cc ../cdjpeg.c ../rdbmp.c ../rdgif.c
../rdppm.c ../rdswitch.c ../rdtarga.c)
set_property(TARGET cjpeg_fuzzer PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS})
target_link_libraries(cjpeg_fuzzer ${FUZZ_LIBRARY} jpeg-static)
install(TARGETS cjpeg_fuzzer RUNTIME DESTINATION ${FUZZ_BINDIR})
macro(add_fuzz_target target source_file)
add_executable(${target}_fuzzer ${source_file})
target_link_libraries(${target}_fuzzer ${FUZZ_LIBRARY} turbojpeg-static)

View File

@@ -10,6 +10,7 @@ cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_STATIC=1 -DENABLE_SHARED=0 \
make "-j$(nproc)" "--load-average=$(nproc)"
make install
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/cjpeg_fuzzer_seed_corpus.zip
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/compress_fuzzer_seed_corpus.zip
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/compress_yuv_fuzzer_seed_corpus.zip
cp $SRC/decompress_fuzzer_seed_corpus.zip $OUT/libjpeg_turbo_fuzzer_seed_corpus.zip

88
fuzz/cjpeg.cc Normal file
View File

@@ -0,0 +1,88 @@
/*
* Copyright (C)2021 D. R. Commander. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the libjpeg-turbo Project nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* This fuzz target wraps cjpeg in order to test esoteric compression options
as well as the GIF and Targa readers. */
#define main cjpeg_main
#define CJPEG_FUZZER
extern "C" {
#include "../cjpeg.c"
}
#undef main
#undef CJPEG_FUZZER
#include <stdint.h>
#include <unistd.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
char filename[FILENAME_MAX] = { 0 };
char *argv1[] = {
(char *)"cjpeg", (char *)"-dct", (char *)"float", (char *)"-memdst",
(char *)"-optimize", (char *)"-quality", (char *)"100,99,98",
(char *)"-restart", (char *)"2", (char *)"-sample", (char *)"4x1,2x2,1x2",
(char *)"-targa", NULL
};
char *argv2[] = {
(char *)"cjpeg", (char *)"-arithmetic", (char *)"-dct", (char *)"float",
(char *)"-memdst", (char *)"-quality", (char *)"90,80,70", (char *)"-rgb",
(char *)"-smooth", (char *)"50", (char *)"-targa", NULL
};
int fd = -1;
#if defined(__has_feature) && __has_feature(memory_sanitizer)
char env[18] = "JSIMD_FORCENONE=1";
/* The libjpeg-turbo SIMD extensions produce false positives with
MemorySanitizer. */
putenv(env);
#endif
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_cjpeg_fuzz.XXXXXX");
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
goto bailout;
argv1[12] = argv2[11] = filename;
cjpeg_main(13, argv1);
cjpeg_main(12, argv2);
argv1[12] = argv2[11] = NULL;
argv1[11] = argv2[10] = filename;
cjpeg_main(12, argv1);
cjpeg_main(11, argv2);
bailout:
if (fd >= 0) {
close(fd);
if (strlen(filename) > 0) unlink(filename);
}
return 0;
}