OSS-Fuzz: cjpeg fuzz target
This commit is contained in:
70
cjpeg.c
70
cjpeg.c
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||||
* Modified 2003-2011 by Guido Vollbeding.
|
* Modified 2003-2011 by Guido Vollbeding.
|
||||||
* libjpeg-turbo Modifications:
|
* 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
|
* For conditions of distribution and use, see the accompanying README.ijg
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
@@ -27,6 +27,9 @@
|
|||||||
* works regardless of which command line style is used.
|
* 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 "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
|
||||||
#include "jversion.h" /* for version message */
|
#include "jversion.h" /* for version message */
|
||||||
#include "jconfigint.h"
|
#include "jconfigint.h"
|
||||||
@@ -146,6 +149,45 @@ boolean memdst; /* for -memdst switch */
|
|||||||
boolean report; /* for -report 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)
|
LOCAL(void)
|
||||||
usage(void)
|
usage(void)
|
||||||
/* complain about bad command line */
|
/* complain about bad command line */
|
||||||
@@ -506,11 +548,16 @@ int
|
|||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct jpeg_compress_struct cinfo;
|
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;
|
struct jpeg_error_mgr jerr;
|
||||||
|
#endif
|
||||||
struct cdjpeg_progress_mgr progress;
|
struct cdjpeg_progress_mgr progress;
|
||||||
int file_index;
|
int file_index;
|
||||||
cjpeg_source_ptr src_mgr;
|
cjpeg_source_ptr src_mgr;
|
||||||
FILE *input_file;
|
FILE *input_file = NULL;
|
||||||
FILE *icc_file;
|
FILE *icc_file;
|
||||||
JOCTET *icc_profile = NULL;
|
JOCTET *icc_profile = NULL;
|
||||||
long icc_len = 0;
|
long icc_len = 0;
|
||||||
@@ -628,6 +675,13 @@ main(int argc, char **argv)
|
|||||||
fclose(icc_file);
|
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) {
|
if (report) {
|
||||||
start_progress_monitor((j_common_ptr)&cinfo, &progress);
|
start_progress_monitor((j_common_ptr)&cinfo, &progress);
|
||||||
progress.report = report;
|
progress.report = report;
|
||||||
@@ -654,6 +708,13 @@ main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
jpeg_stdio_dest(&cinfo, output_file);
|
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 */
|
/* Start compressor */
|
||||||
jpeg_start_compress(&cinfo, TRUE);
|
jpeg_start_compress(&cinfo, TRUE);
|
||||||
|
|
||||||
@@ -681,13 +742,14 @@ main(int argc, char **argv)
|
|||||||
end_progress_monitor((j_common_ptr)&cinfo);
|
end_progress_monitor((j_common_ptr)&cinfo);
|
||||||
|
|
||||||
if (memdst) {
|
if (memdst) {
|
||||||
|
#ifndef CJPEG_FUZZER
|
||||||
fprintf(stderr, "Compressed size: %lu bytes\n", outsize);
|
fprintf(stderr, "Compressed size: %lu bytes\n", outsize);
|
||||||
|
#endif
|
||||||
free(outbuffer);
|
free(outbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(icc_profile);
|
free(icc_profile);
|
||||||
|
|
||||||
/* All done. */
|
/* All done. */
|
||||||
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
|
return (jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
|
||||||
return 0; /* suppress no-return-value warnings */
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ set(EFFECTIVE_CXX_FLAGS
|
|||||||
"${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
|
"${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
|
||||||
message(STATUS "C++ Compiler flags = ${EFFECTIVE_CXX_FLAGS}")
|
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)
|
macro(add_fuzz_target target source_file)
|
||||||
add_executable(${target}_fuzzer ${source_file})
|
add_executable(${target}_fuzzer ${source_file})
|
||||||
target_link_libraries(${target}_fuzzer ${FUZZ_LIBRARY} turbojpeg-static)
|
target_link_libraries(${target}_fuzzer ${FUZZ_LIBRARY} turbojpeg-static)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_STATIC=1 -DENABLE_SHARED=0 \
|
|||||||
make "-j$(nproc)" "--load-average=$(nproc)"
|
make "-j$(nproc)" "--load-average=$(nproc)"
|
||||||
make install
|
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_fuzzer_seed_corpus.zip
|
||||||
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/compress_yuv_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
|
cp $SRC/decompress_fuzzer_seed_corpus.zip $OUT/libjpeg_turbo_fuzzer_seed_corpus.zip
|
||||||
|
|||||||
88
fuzz/cjpeg.cc
Normal file
88
fuzz/cjpeg.cc
Normal 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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user