From b736acdd85b7e1f68d0a93642fdd51489327c971 Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Sat, 8 May 2021 14:46:57 +0200 Subject: [PATCH] Applied updates and added item OSS-Fuzz target --- common/types.h.in | 10 +++ configure.ac | 2 +- m4/zlib.m4 | 17 +++- ossfuzz/Makefile.am | 23 +++++- ossfuzz/item_fuzzer.cc | 133 +++++++++++++++++++++++++++++++ pypff/pypff_datetime.c | 4 +- pypff/pypff_datetime.h | 2 +- pypff/pypff_encryption_types.c | 2 +- pypff/pypff_file.c | 2 +- pypff/pypff_file_content_types.c | 2 +- pypff/pypff_file_types.c | 2 +- pypff/pypff_item.c | 2 +- pypff/pypff_item_types.c | 2 +- pypff/pypff_items.c | 2 +- pypff/pypff_record_entries.c | 2 +- pypff/pypff_record_entry.c | 2 +- pypff/pypff_record_set.c | 2 +- pypff/pypff_record_sets.c | 2 +- 18 files changed, 196 insertions(+), 17 deletions(-) create mode 100644 ossfuzz/item_fuzzer.cc diff --git a/common/types.h.in b/common/types.h.in index e0cfac6e..6fd00f98 100644 --- a/common/types.h.in +++ b/common/types.h.in @@ -305,6 +305,16 @@ typedef int system_integer_t; #define UINT32_MAX (0xffffffffUL) #endif +/* The minimum signed 64-bit integer is -9223372036854775808 (0x8000000000000000) + */ +#if !defined( INT64_MIN ) +#if defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x0560 ) +#define INT64_MIN (0x8000000000000000UL) +#else +#define INT64_MIN (0x8000000000000000ULL) +#endif +#endif /* !defined( INT64_MIN ) */ + /* The maximum signed 64-bit integer is 9223372036854775807 (0x7fffffffffffffff) */ #if !defined( INT64_MAX ) diff --git a/configure.ac b/configure.ac index e365a1ff..1266c48b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ( 2.59 ) AC_INIT( [libpff], - [20210424], + [20210508], [joachim.metz@gmail.com]) AC_CONFIG_SRCDIR( diff --git a/m4/zlib.m4 b/m4/zlib.m4 index a98333c5..28caa494 100644 --- a/m4/zlib.m4 +++ b/m4/zlib.m4 @@ -1,6 +1,6 @@ dnl Checks for zlib required headers and functions dnl -dnl Version: 20200712 +dnl Version: 20201230 dnl Function to detect if zlib is available AC_DEFUN([AX_ZLIB_CHECK_LIB], @@ -189,6 +189,21 @@ AC_DEFUN([AX_ZLIB_CHECK_INFLATE], inflateEnd, [ac_zlib_dummy=yes], [ac_cv_inflate=local]) + AC_CHECK_LIB( + z, + inflateGetDictionary, + [ac_zlib_dummy=yes], + [ac_cv_inflate=local]) + AC_CHECK_LIB( + z, + inflatePrime, + [ac_zlib_dummy=yes], + [ac_cv_inflate=local]) + AC_CHECK_LIB( + z, + inflateSetDictionary, + [ac_zlib_dummy=yes], + [ac_cv_inflate=local]) AS_IF( [test "x$ac_cv_inflate" = xzlib], diff --git a/ossfuzz/Makefile.am b/ossfuzz/Makefile.am index 8566aeaf..3fc26ccd 100644 --- a/ossfuzz/Makefile.am +++ b/ossfuzz/Makefile.am @@ -12,7 +12,8 @@ AM_CPPFLAGS = \ @LIBBFIO_CPPFLAGS@ bin_PROGRAMS = \ - file_fuzzer + file_fuzzer \ + item_fuzzer file_fuzzer_SOURCES = \ file_fuzzer.cc \ @@ -31,6 +32,24 @@ file_fuzzer_LDADD = \ @LIBCLOCALE_LIBADD@ \ @LIBCERROR_LIBADD@ \ @LIBINTL@ + +item_fuzzer_SOURCES = \ + item_fuzzer.cc \ + ossfuzz_libbfio.h \ + ossfuzz_libpff.h + +item_fuzzer_LDADD = \ + @LIB_FUZZING_ENGINE@ \ + @LIBBFIO_LIBADD@ \ + @LIBCPATH_LIBADD@ \ + @LIBCFILE_LIBADD@ \ + @LIBUNA_LIBADD@ \ + @LIBCDATA_LIBADD@ \ + ../libpff/libpff.la \ + @LIBCNOTIFY_LIBADD@ \ + @LIBCLOCALE_LIBADD@ \ + @LIBCERROR_LIBADD@ \ + @LIBINTL@ endif MAINTAINERCLEANFILES = \ @@ -42,4 +61,6 @@ distclean: clean splint: @echo "Running splint on file_fuzzer ..." -splint -preproc -redef $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(file_fuzzer_SOURCES) + @echo "Running splint on item_fuzzer ..." + -splint -preproc -redef $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(item_fuzzer_SOURCES) diff --git a/ossfuzz/item_fuzzer.cc b/ossfuzz/item_fuzzer.cc new file mode 100644 index 00000000..5ab978a7 --- /dev/null +++ b/ossfuzz/item_fuzzer.cc @@ -0,0 +1,133 @@ +/* + * OSS-Fuzz target for libpff item type + * + * Copyright (C) 2008-2020, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This program 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 3 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 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, see . + */ + +#include +#include + +/* Note that some of the OSS-Fuzz engines use C++ + */ +extern "C" { + +#include "ossfuzz_libbfio.h" +#include "ossfuzz_libpff.h" + +#if !defined( LIBPFF_HAVE_BFIO ) + +/* Opens a file using a Basic File IO (bfio) handle + * Returns 1 if successful or -1 on error + */ +LIBPFF_EXTERN \ +int libpff_file_open_file_io_handle( + libpff_file_t *file, + libbfio_handle_t *file_io_handle, + int access_flags, + libpff_error_t **error ); + +#endif /* !defined( LIBPFF_HAVE_BFIO ) */ + +int LLVMFuzzerTestOneInput( + const uint8_t *data, + size_t size ) +{ + libbfio_handle_t *file_io_handle = NULL; + libpff_file_t *file = NULL; + libpff_item_t *root_folder = NULL; + libpff_item_t *sub_item = NULL; + int number_of_sub_items = 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( libpff_file_initialize( + &file, + NULL ) != 1 ) + { + goto on_error_libbfio; + } + if( libpff_file_open_file_io_handle( + file, + file_io_handle, + LIBPFF_OPEN_READ, + NULL ) != 1 ) + { + goto on_error_libpff_file; + } + if( libpff_file_get_root_folder( + file, + &root_folder, + NULL ) == 1 ) + { + if( libpff_item_get_number_of_sub_items( + root_folder, + &number_of_sub_items, + NULL ) != 1 ) + { + goto on_error_libpff_root_folder; + } + if( number_of_sub_items > 0 ) + { + if( libpff_item_get_sub_item( + root_folder, + 0, + &sub_item, + NULL ) != 1 ) + { + goto on_error_libpff_root_folder; + } + libpff_item_free( + &sub_item, + NULL ); + } +on_error_libpff_root_folder: + libpff_item_free( + &root_folder, + NULL ); + } + libpff_file_close( + file, + NULL ); + +on_error_libpff_file: + libpff_file_free( + &file, + NULL ); + +on_error_libbfio: + libbfio_handle_free( + &file_io_handle, + NULL ); + + return( 0 ); +} + +} /* extern "C" */ + diff --git a/pypff/pypff_datetime.c b/pypff/pypff_datetime.c index 5c962cf0..b4e15ca8 100644 --- a/pypff/pypff_datetime.c +++ b/pypff/pypff_datetime.c @@ -37,7 +37,7 @@ PyObject *pypff_datetime_new_from_time_elements( uint8_t hours, uint8_t minutes, uint8_t seconds, - uint8_t micro_seconds ) + uint32_t micro_seconds ) { PyObject *datetime_object = NULL; static char *function = "pypff_datetime_new_from_time_elements"; @@ -163,7 +163,7 @@ PyObject *pypff_datetime_new_from_time_elements( (int) hours, (int) minutes, (int) seconds, - 0 ); + (int) micro_seconds ); return( datetime_object ); } diff --git a/pypff/pypff_datetime.h b/pypff/pypff_datetime.h index 9d8e3a94..5a0a9ab3 100644 --- a/pypff/pypff_datetime.h +++ b/pypff/pypff_datetime.h @@ -37,7 +37,7 @@ PyObject *pypff_datetime_new_from_time_elements( uint8_t hours, uint8_t minutes, uint8_t seconds, - uint8_t micro_seconds ); + uint32_t micro_seconds ); PyObject *pypff_datetime_new_from_fat_date_time( uint32_t fat_date_time ); diff --git a/pypff/pypff_encryption_types.c b/pypff/pypff_encryption_types.c index 0736561b..b27cd1af 100644 --- a/pypff/pypff_encryption_types.c +++ b/pypff/pypff_encryption_types.c @@ -242,7 +242,7 @@ PyObject *pypff_encryption_types_new( return( NULL ); } -/* Intializes an encryption types object +/* Initializes an encryption types object * Returns 0 if successful or -1 on error */ int pypff_encryption_types_init( diff --git a/pypff/pypff_file.c b/pypff/pypff_file.c index dd49efc8..bdbb897f 100644 --- a/pypff/pypff_file.c +++ b/pypff/pypff_file.c @@ -328,7 +328,7 @@ PyTypeObject pypff_file_type_object = { 0 }; -/* Intializes a file object +/* Initializes a file object * Returns 0 if successful or -1 on error */ int pypff_file_init( diff --git a/pypff/pypff_file_content_types.c b/pypff/pypff_file_content_types.c index 4a4c178f..72018c5b 100644 --- a/pypff/pypff_file_content_types.c +++ b/pypff/pypff_file_content_types.c @@ -242,7 +242,7 @@ PyObject *pypff_file_content_types_new( return( NULL ); } -/* Intializes a file content types object +/* Initializes a file content types object * Returns 0 if successful or -1 on error */ int pypff_file_content_types_init( diff --git a/pypff/pypff_file_types.c b/pypff/pypff_file_types.c index 4a61593a..2a63596f 100644 --- a/pypff/pypff_file_types.c +++ b/pypff/pypff_file_types.c @@ -242,7 +242,7 @@ PyObject *pypff_file_types_new( return( NULL ); } -/* Intializes a file types object +/* Initializes a file types object * Returns 0 if successful or -1 on error */ int pypff_file_types_init( diff --git a/pypff/pypff_item.c b/pypff/pypff_item.c index cbf89723..070460ff 100644 --- a/pypff/pypff_item.c +++ b/pypff/pypff_item.c @@ -283,7 +283,7 @@ PyObject *pypff_item_new( return( NULL ); } -/* Intializes an item object +/* Initializes an item object * Returns 0 if successful or -1 on error */ int pypff_item_init( diff --git a/pypff/pypff_item_types.c b/pypff/pypff_item_types.c index baf75ca9..30d65e77 100644 --- a/pypff/pypff_item_types.c +++ b/pypff/pypff_item_types.c @@ -620,7 +620,7 @@ PyObject *pypff_item_types_new( return( NULL ); } -/* Intializes an item types object +/* Initializes an item types object * Returns 0 if successful or -1 on error */ int pypff_item_types_init( diff --git a/pypff/pypff_items.c b/pypff/pypff_items.c index 9ddf4ccb..f7b2f79c 100644 --- a/pypff/pypff_items.c +++ b/pypff/pypff_items.c @@ -215,7 +215,7 @@ PyObject *pypff_items_new( return( NULL ); } -/* Intializes an items sequence and iterator object +/* Initializes an items sequence and iterator object * Returns 0 if successful or -1 on error */ int pypff_items_init( diff --git a/pypff/pypff_record_entries.c b/pypff/pypff_record_entries.c index cd84072c..bd948b0a 100644 --- a/pypff/pypff_record_entries.c +++ b/pypff/pypff_record_entries.c @@ -215,7 +215,7 @@ PyObject *pypff_record_entries_new( return( NULL ); } -/* Intializes a record entries sequence and iterator object +/* Initializes a record entries sequence and iterator object * Returns 0 if successful or -1 on error */ int pypff_record_entries_init( diff --git a/pypff/pypff_record_entry.c b/pypff/pypff_record_entry.c index 8340db1f..1509b24a 100644 --- a/pypff/pypff_record_entry.c +++ b/pypff/pypff_record_entry.c @@ -319,7 +319,7 @@ PyObject *pypff_record_entry_new( return( NULL ); } -/* Intializes a record entry object +/* Initializes a record entry object * Returns 0 if successful or -1 on error */ int pypff_record_entry_init( diff --git a/pypff/pypff_record_set.c b/pypff/pypff_record_set.c index 70e6f5b6..bf0744a6 100644 --- a/pypff/pypff_record_set.c +++ b/pypff/pypff_record_set.c @@ -228,7 +228,7 @@ PyObject *pypff_record_set_new( return( NULL ); } -/* Intializes a record set object +/* Initializes a record set object * Returns 0 if successful or -1 on error */ int pypff_record_set_init( diff --git a/pypff/pypff_record_sets.c b/pypff/pypff_record_sets.c index 2b9bfe59..13e8e7d4 100644 --- a/pypff/pypff_record_sets.c +++ b/pypff/pypff_record_sets.c @@ -224,7 +224,7 @@ PyObject *pypff_record_sets_new( return( NULL ); } -/* Intializes a record sets object +/* Initializes a record sets object * Returns 0 if successful or -1 on error */ int pypff_record_sets_init(