improve fuzz targets and oss-fuzz integration
It replaces current fuzz setup with 5 new fuzzers integrating them with top-level Makefile. It now supports multiple fuzzing engines and Google's oss-fuzz. By default, the fuzzers are linked against an standalone runner to easily reproduce bugs.
This commit is contained in:
parent
2da56b918d
commit
3ea72c286e
@ -5,7 +5,8 @@ SUBDIRS = \
|
||||
po \
|
||||
man \
|
||||
doc \
|
||||
test
|
||||
test \
|
||||
fuzz
|
||||
|
||||
EXTRA_DIST = \
|
||||
m4 \
|
||||
|
@ -1388,6 +1388,13 @@ if test x"$with_libexif" != x"no"; then
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
fi
|
||||
|
||||
# fuzzing
|
||||
AC_ARG_VAR([LIB_FUZZING_ENGINE],
|
||||
[fuzzing library, e.g. /path/to/libFuzzer.a])
|
||||
if test x"$LIB_FUZZING_ENGINE" = x; then
|
||||
LIB_FUZZING_ENGINE="libstandaloneengine.a"
|
||||
fi
|
||||
|
||||
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS
|
||||
# sort includes to get longer, more specific dirs first
|
||||
# helps, for example, selecting graphicsmagick over imagemagick
|
||||
@ -1452,6 +1459,7 @@ AC_OUTPUT([
|
||||
doc/Makefile
|
||||
doc/libvips-docs.xml
|
||||
po/Makefile.in
|
||||
fuzz/Makefile
|
||||
])
|
||||
|
||||
AC_MSG_RESULT([dnl
|
||||
|
20
fuzz/Makefile.am
Normal file
20
fuzz/Makefile.am
Normal file
@ -0,0 +1,20 @@
|
||||
FUZZPROGS = \
|
||||
jpegsave_buffer_fuzzer \
|
||||
pngsave_buffer_fuzzer \
|
||||
webpsave_buffer_fuzzer \
|
||||
sharpen_fuzzer \
|
||||
thumbnail_fuzzer
|
||||
|
||||
AM_DEFAULT_SOURCE_EXT = .cc
|
||||
|
||||
FUZZLIBS = libstandaloneengine.a
|
||||
|
||||
# Include debug symbols by default as recommended by libfuzzer
|
||||
AM_CXXFLAGS = -g -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
|
||||
AM_LDFLAGS = @LDFLAGS@
|
||||
LDADD = ${top_builddir}/libvips/libvips.la @VIPS_LIBS@ @LIB_FUZZING_ENGINE@
|
||||
|
||||
libstandaloneengine_a_SOURCES = StandaloneFuzzTargetMain.c
|
||||
|
||||
noinst_PROGRAMS = $(FUZZPROGS)
|
||||
noinst_LIBRARIES = $(FUZZLIBS)
|
46
fuzz/StandaloneFuzzTargetMain.c
Normal file
46
fuzz/StandaloneFuzzTargetMain.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*===- StandaloneFuzzTargetMain.c - standalone main() for fuzz targets. ---===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// This main() function can be linked to a fuzz target (i.e. a library
|
||||
// that exports LLVMFuzzerTestOneInput() and possibly LLVMFuzzerInitialize())
|
||||
// instead of libFuzzer. This main() function will not perform any fuzzing
|
||||
// but will simply feed all input files one by one to the fuzz target.
|
||||
//
|
||||
// Use this file to provide reproducers for bugs when linking against libFuzzer
|
||||
// or other fuzzing engine is undesirable.
|
||||
//===----------------------------------------------------------------------===*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);
|
||||
extern int LLVMFuzzerInitialize(int *argc, char ***argv);
|
||||
int main(int argc, char **argv) {
|
||||
const char *progname;
|
||||
if ((progname = strrchr(argv[0], '/')))
|
||||
progname++;
|
||||
else
|
||||
progname = argv[0];
|
||||
fprintf(stderr, "%s: running %d inputs\n", progname, argc - 1);
|
||||
LLVMFuzzerInitialize(&argc, &argv);
|
||||
for (int i = 1; i < argc; i++) {
|
||||
fprintf(stderr, "Running: %s\n", argv[i]);
|
||||
FILE *f = fopen(argv[i], "r+");
|
||||
assert(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
long len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char *buf = (unsigned char*)malloc(len);
|
||||
size_t n_read = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
assert(n_read == len);
|
||||
LLVMFuzzerTestOneInput(buf, len);
|
||||
free(buf);
|
||||
fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
|
||||
}
|
||||
}
|
30
fuzz/jpegsave_buffer_fuzzer.cc
Normal file
30
fuzz/jpegsave_buffer_fuzzer.cc
Normal file
@ -0,0 +1,30 @@
|
||||
#include <vips/vips.h>
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerInitialize( int *argc, char ***argv )
|
||||
{
|
||||
vips_concurrency_set( 1 );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
{
|
||||
VipsImage *image;
|
||||
size_t len;
|
||||
void *buf;
|
||||
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) ) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( vips_jpegsave_buffer( image, &buf, &len, NULL ) ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
g_free( buf );
|
||||
g_object_unref( image );
|
||||
|
||||
return( 0 );
|
||||
}
|
30
fuzz/pngsave_buffer_fuzzer.cc
Normal file
30
fuzz/pngsave_buffer_fuzzer.cc
Normal file
@ -0,0 +1,30 @@
|
||||
#include <vips/vips.h>
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerInitialize( int *argc, char ***argv )
|
||||
{
|
||||
vips_concurrency_set( 1 );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
{
|
||||
VipsImage *image;
|
||||
void *buf;
|
||||
size_t len;
|
||||
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) ) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( vips_pngsave_buffer( image, &buf, &len, NULL ) ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
g_free( buf );
|
||||
g_object_unref( image );
|
||||
|
||||
return( 0 );
|
||||
}
|
31
fuzz/sharpen_fuzzer.cc
Normal file
31
fuzz/sharpen_fuzzer.cc
Normal file
@ -0,0 +1,31 @@
|
||||
#include <vips/vips.h>
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerInitialize( int *argc, char ***argv )
|
||||
{
|
||||
vips_concurrency_set( 1 );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
{
|
||||
VipsImage *in, *out;
|
||||
double d;
|
||||
|
||||
if( !(in = vips_image_new_from_buffer( data, size, "", NULL )) ) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( vips_sharpen( in, &out, NULL ) ) {
|
||||
g_object_unref( in );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
vips_avg( out, &d, NULL );
|
||||
|
||||
g_object_unref( out );
|
||||
g_object_unref( in );
|
||||
|
||||
return( 0 );
|
||||
}
|
42
fuzz/thumbnail_fuzzer.cc
Normal file
42
fuzz/thumbnail_fuzzer.cc
Normal file
@ -0,0 +1,42 @@
|
||||
#include <vips/vips.h>
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerInitialize( int *argc, char ***argv )
|
||||
{
|
||||
vips_concurrency_set( 1 );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
{
|
||||
VipsImage *in, *out;
|
||||
size_t width, height;
|
||||
double d;
|
||||
|
||||
if( !(in = vips_image_new_from_buffer( data, size, "", NULL )) ) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
width = in->Xsize;
|
||||
height = in->Ysize;
|
||||
|
||||
/* Skip big images. It is likely to timeout.
|
||||
*/
|
||||
if ( width * height > 256 * 256 ) {
|
||||
g_object_unref( in );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( vips_thumbnail_image( in, &out, 42, NULL ) ) {
|
||||
g_object_unref( in );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
vips_avg( out, &d, NULL );
|
||||
|
||||
g_object_unref( out );
|
||||
g_object_unref( in );
|
||||
|
||||
return( 0 );
|
||||
}
|
30
fuzz/webpsave_buffer_fuzzer.cc
Normal file
30
fuzz/webpsave_buffer_fuzzer.cc
Normal file
@ -0,0 +1,30 @@
|
||||
#include <vips/vips.h>
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerInitialize( int *argc, char ***argv )
|
||||
{
|
||||
vips_concurrency_set( 1 );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerTestOneInput( const guint8 *data, size_t size )
|
||||
{
|
||||
VipsImage *image;
|
||||
void *buf;
|
||||
size_t len;
|
||||
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) ) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
if( vips_webpsave_buffer( image, &buf, &len, NULL ) ) {
|
||||
g_object_unref( image );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
g_free( buf );
|
||||
g_object_unref( image );
|
||||
|
||||
return( 0 );
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
noinst_LTLIBRARIES = libfuzz.la
|
||||
|
||||
libfuzz_la_SOURCES = \
|
||||
fuzz_new_from_buffer.c
|
||||
|
||||
AM_CPPFLAGS = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
|
@ -1,64 +0,0 @@
|
||||
/* fuzz targets for libfuzzer
|
||||
*
|
||||
* 28/7/17
|
||||
* - first attempt
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
#define VIPS_DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
int
|
||||
vips__fuzztarget_new_from_buffer( const guint8 *data, size_t size )
|
||||
{
|
||||
VipsImage *image;
|
||||
double d;
|
||||
|
||||
/* Have one for each format as well.
|
||||
*/
|
||||
if( !(image = vips_image_new_from_buffer( data, size, "", NULL )) )
|
||||
/* libfuzzer does not allow error return.
|
||||
*/
|
||||
return( 0 );
|
||||
|
||||
if( vips_avg( image, &d, NULL ) )
|
||||
return( 0 );
|
||||
|
||||
g_object_unref( image );
|
||||
|
||||
return( 0 );
|
||||
}
|
Loading…
Reference in New Issue
Block a user