fuzzerfidentify: use libfuzzer

This commit is contained in:
Christophe Grenier 2018-12-08 08:33:30 +01:00
parent 7da08fa5b3
commit 2d603b6d1d
3 changed files with 137 additions and 3 deletions

View file

@ -6,7 +6,7 @@ AC_INIT([testdisk],[7.1-WIP],[grenier@cgsecurity.org])
AC_LANG(C)
sinclude(acx_pthread.m4)
sinclude(mkdir.m4)
TESTDISKDATE="September 2018"
TESTDISKDATE="December 2018"
AC_SUBST(TESTDISKDATE)
AC_DEFINE_UNQUOTED([TESTDISKDATE],"$TESTDISKDATE",[Date of release])
AC_CONFIG_AUX_DIR(config)
@ -1030,10 +1030,10 @@ then
fi
photorecf_LDADD=$photorec_LDADD
fuzzerfidentify_LDADD="-fsanitize=fuzzer $fidentify_LDADD"
CFLAGS="$CFLAGS $coverage_flags"
CXXFLAGS="$CXXFLAGS $coverage_flags"
CPPFLAGS="$CPPFLAGS $coverage_flags"
AC_SUBST(CFLAGS)
AC_SUBST(CXXFLAGS)
AC_SUBST(CPPFLAGS)
@ -1042,6 +1042,7 @@ AC_SUBST(MOC)
AC_SUBST(LRELEASE)
AC_SUBST(QT_SELECT)
AC_SUBST(fidentify_LDADD)
AC_SUBST(fuzzerfidentify_LDADD)
AC_SUBST(testdisk_LDADD)
AC_SUBST(photorec_LDADD)
AC_SUBST(photorecf_LDADD)

View file

@ -12,7 +12,7 @@ if USEQT
endif
bin_PROGRAMS = testdisk photorec fidentify $(QPHOTOREC)
EXTRA_PROGRAMS = photorecf
EXTRA_PROGRAMS = photorecf fuzzerfidentify
base_C = autoset.c common.c crc.c ewf.c fnctdsk.c hdaccess.c hdcache.c hdwin32.c hidden.c hpa_dco.c intrf.c iso.c list_sort.c log.c log_part.c misc.c msdos.c parti386.c partgpt.c parthumax.c partmac.c partsun.c partnone.c partxbox.c io_redir.c ntfs_io.c ntfs_utl.c partauto.c sudo.c unicode.c win32.c
base_H = alignio.h autoset.h common.h crc.h ewf.h fnctdsk.h hdaccess.h hdwin32.h hidden.h guid_cmp.h guid_cpy.h hdcache.h hpa_dco.h intrf.h iso.h iso9660.h lang.h list.h list_sort.h log.h log_part.h misc.h types.h io_redir.h msdos.h ntfs_utl.h parti386.h partgpt.h parthumax.h partmac.h partsun.h partxbox.h partauto.h sudo.h unicode.h win32.h
@ -383,6 +383,8 @@ nodist_qphotorec_SOURCES = moc_qphotorec.cpp rcc_qphotorec.cpp rcc_qphotorec_loc
fidentify_SOURCES = fidentify.c common.c common.h misc.c misc.h phcfg.c phcfg.h setdate.c setdate.h $(file_C) $(file_H) log.c log.h crc.c crc.h ext2_common.c fat_common.c fat_common.h suspend_no.c
fuzzerfidentify_SOURCES = fuzzerfidentify.cpp common.c common.h misc.c misc.h phcfg.c phcfg.h setdate.c setdate.h $(file_C) $(file_H) log.c log.h crc.c crc.h ext2_common.c fat_common.c fat_common.h suspend_no.c
QT_QM=$(QT_TS:.ts=.qm)
SECONDARY: $(QT_QM)

131
src/fuzzerfidentify.cpp Normal file
View file

@ -0,0 +1,131 @@
/*
File: fuzzerfidentify.cpp
Copyright (C) 2018 Christophe GRENIER <grenier@cgsecurity.org>
This software is free software; you can redistribute it and/or modify
it under the terms of the GNU 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <dirent.h>
#include "types.h"
#include "common.h"
#include "filegen.h"
#include <sys/types.h>
#include <unistd.h>
extern file_enable_t list_file_enable[];
extern file_check_list_t file_check_list;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
const size_t blocksize=65536;
static unsigned char *buffer_start=NULL;
static file_stat_t *file_stats=NULL;
static char *filename=NULL;
uint8_t *buffer;
if(Size == 0)
return 0;
if(filename==NULL)
{
pid_t pid=getpid();
filename=(char *)MALLOC(64);
sprintf(filename, "sample%u", pid);
}
if(file_stats==NULL)
{
/* Enable all file formats */
file_enable_t *file_enable;
for(file_enable=list_file_enable;file_enable->file_hint!=NULL;file_enable++)
file_enable->enable=1;
file_stats=init_file_stats(list_file_enable);
}
if(buffer_start==NULL)
{
buffer_start=(unsigned char *)MALLOC(2*blocksize);
}
buffer=buffer_start+blocksize;
memcpy(buffer, Data, (Size < blocksize ? Size : blocksize));
{
struct td_list_head *tmpl;
file_recovery_t file_recovery_new;
file_recovery_t file_recovery;
reset_file_recovery(&file_recovery);
file_recovery.blocksize=blocksize;
file_recovery_new.blocksize=blocksize;
file_recovery_new.file_stat=NULL;
td_list_for_each(tmpl, &file_check_list.list)
{
struct td_list_head *tmp;
const file_check_list_t *pos=td_list_entry_const(tmpl, const file_check_list_t, list);
if(pos->offset <= blocksize)
{
td_list_for_each(tmp, &pos->file_checks[buffer[pos->offset]].list)
{
const file_check_t *file_check=td_list_entry_const(tmp, const file_check_t, list);
if((file_check->length==0 ||
(file_check->offset+file_check->length <=blocksize &&
memcmp(buffer + file_check->offset, file_check->value, file_check->length)==0)) &&
file_check->header_check(buffer, blocksize, 0, &file_recovery, &file_recovery_new)!=0)
{
file_recovery_new.file_stat=file_check->file_stat;
break;
}
}
}
if(file_recovery_new.file_stat!=NULL)
break;
}
#if 0
if( file_recovery_new.file_stat!=NULL && file_recovery_new.file_stat->file_hint!=NULL &&
file_recovery_new.file_check!=NULL)
{
FILE *out;
file_recovery_new.file_size=Size;
file_recovery_new.calculated_file_size=Size;
out=fopen(filename, "wb");
fwrite(Data, Size, 1, out);
file_recovery_new.handle=out;
(file_recovery_new.file_check)(&file_recovery_new);
fclose(out);
// unlink(filename);
}
#endif
}
return 0; // Non-zero return values are reserved for future use.
}