Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions ossfuzz/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ AM_CPPFLAGS = \
@LIBBFIO_CPPFLAGS@

bin_PROGRAMS = \
volume_fuzzer
volume_fuzzer \
read_fuzzer

volume_fuzzer_SOURCES = \
ossfuzz_libbfio.h \
Expand All @@ -31,6 +32,24 @@ volume_fuzzer_LDADD = \
@LIBCLOCALE_LIBADD@ \
@LIBCERROR_LIBADD@ \
@LIBINTL@

read_fuzzer_SOURCES = \
ossfuzz_libbfio.h \
ossfuzz_libvshadow.h \
read_fuzzer.cc

read_fuzzer_LDADD = \
@LIB_FUZZING_ENGINE@ \
@LIBBFIO_LIBADD@ \
@LIBCPATH_LIBADD@ \
@LIBCFILE_LIBADD@ \
@LIBUNA_LIBADD@ \
@LIBCDATA_LIBADD@ \
../libvshadow/libvshadow.la \
@LIBCNOTIFY_LIBADD@ \
@LIBCLOCALE_LIBADD@ \
@LIBCERROR_LIBADD@ \
@LIBINTL@
endif

DISTCLEANFILES = \
Expand All @@ -40,4 +59,3 @@ DISTCLEANFILES = \
splint-local:
@echo "Running splint on volume_fuzzer ..."
-splint -preproc -redef $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(volume_fuzzer_SOURCES)

147 changes: 147 additions & 0 deletions ossfuzz/read_fuzzer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* OSS-Fuzz target for the libvshadow store read-buffer (data) path
*
* The existing volume_fuzzer only opens and closes the volume, so the
* per-store block descriptor / diff-area reconstruction logic is never
* reached. This target additionally enumerates the stores and reads their
* data so the store reconstruction parsers are exercised.
*/

#include <stddef.h>
#include <stdint.h>

/* Note that some of the OSS-Fuzz engines use C++
*/
extern "C" {

#include "ossfuzz_libbfio.h"
#include "ossfuzz_libvshadow.h"

#if !defined( LIBVSHADOW_HAVE_BFIO )

LIBVSHADOW_EXTERN \
int libvshadow_volume_open_file_io_handle(
libvshadow_volume_t *volume,
libbfio_handle_t *file_io_handle,
int access_flags,
libvshadow_error_t **error );

#endif /* !defined( LIBVSHADOW_HAVE_BFIO ) */

int LLVMFuzzerTestOneInput(
const uint8_t *data,
size_t size )
{
libbfio_handle_t *file_io_handle = NULL;
libvshadow_volume_t *volume = NULL;
libvshadow_store_t *store = NULL;
int number_of_stores = 0;
int store_index = 0;

if( libbfio_memory_range_initialize(
&file_io_handle,
NULL ) != 1 )
{
return( 0 );
}
if( libbfio_memory_range_set(
file_io_handle,
(uint8_t *) data,
size,
NULL ) != 1 )
{
goto on_error_libbfio;
}
if( libvshadow_volume_initialize(
&volume,
NULL ) != 1 )
{
goto on_error_libbfio;
}
if( libvshadow_volume_open_file_io_handle(
volume,
file_io_handle,
LIBVSHADOW_OPEN_READ,
NULL ) != 1 )
{
goto on_error_libvshadow;
}
if( libvshadow_volume_get_number_of_stores(
volume,
&number_of_stores,
NULL ) != 1 )
{
goto on_error_close;
}
/* Cap the number of stores examined to bound run time. */
if( number_of_stores > 16 )
{
number_of_stores = 16;
}
for( store_index = 0;
store_index < number_of_stores;
store_index++ )
{
if( libvshadow_volume_get_store(
volume,
store_index,
&store,
NULL ) != 1 )
{
continue;
}
/* Read the store to drive the block descriptor reconstruction. */
{
size64_t store_size = 0;

if( libvshadow_store_get_size(
store,
&store_size,
NULL ) == 1 )
{
uint8_t buffer[ 4096 ];
off64_t offset = 0;
int iterations = 0;

while( ( offset < (off64_t) store_size )
&& ( iterations < 1024 ) )
{
ssize_t read_count = libvshadow_store_read_buffer_at_offset(
store,
buffer,
sizeof( buffer ),
offset,
NULL );

if( read_count <= 0 )
{
break;
}
offset += read_count;
iterations++;
}
}
}
libvshadow_store_free(
&store,
NULL );
}
on_error_close:
libvshadow_volume_close(
volume,
NULL );

on_error_libvshadow:
libvshadow_volume_free(
&volume,
NULL );

on_error_libbfio:
libbfio_handle_free(
&file_io_handle,
NULL );

return( 0 );
}

} /* extern "C" */
Loading