mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
tools/insn-fuzz: Support AFL's afl-clang-fast mode
AFL has an alternative llvm-base instrumentation mode, which has much lower overhead than the traditional afl-gcc. One extra ability is to chose exactly where the master process gets initialised to, before being forked for testing. This point is chosen after the call to LLVMFuzzerInitialize(), so the stack isn't being remapped executable for every test. Another extra ability is to feed multiple inputs into a single test process, to reduce the number of fork() calls required overall. Two caveats are that if stdin is used for data, it must be unbuffered, and if input is passed via a command line parameter, the underlying file must be opened and closed on each iteration. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
1 parent
63092064eb
commit
69f4633817
2 files changed
+43
-27
No files matched your search
@@ -18,7 +18,15 @@ Use the x86 instruction emulator fuzzer as an example.
|
||||
2. run the following commands to build:
|
||||
$ cd tools/fuzz/x86_instruction_emulator
|
||||
$ make distclean
|
||||
$ make CC=$AFLPATH/afl-gcc afl # produces afl-harness
|
||||
|
||||
If you have a new enough version of Clang/LLVM and have configured AFL's
|
||||
llvm_mode, make use of afl-clang-fast:
|
||||
|
||||
$ make CC=$AFLPATH/afl-clang-fast afl # produces afl-harness
|
||||
|
||||
If not, use the default afl-gcc:
|
||||
|
||||
$ make CC=$AFLPATH/afl-gcc afl # produces afl-harness
|
||||
|
||||
3. provide initial test case (fuzzer dependent, see afl-*.c):
|
||||
$ mkdir testcase_dir
|
||||
|
||||
@@ -17,6 +17,7 @@ int main(int argc, char **argv)
|
||||
size_t size;
|
||||
FILE *fp = NULL;
|
||||
|
||||
setbuf(stdin, NULL);
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
while ( 1 )
|
||||
@@ -61,38 +62,45 @@ int main(int argc, char **argv)
|
||||
if ( LLVMFuzzerInitialize(&argc, &argv) )
|
||||
exit(-1);
|
||||
|
||||
if ( fp != stdin ) /* If not using stdin, open the provided file. */
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
__AFL_INIT();
|
||||
|
||||
while ( __AFL_LOOP(1000) )
|
||||
#endif
|
||||
{
|
||||
fp = fopen(argv[optind], "rb");
|
||||
if ( fp == NULL )
|
||||
if ( fp != stdin ) /* If not using stdin, open the provided file. */
|
||||
{
|
||||
perror("fopen");
|
||||
fp = fopen(argv[optind], "rb");
|
||||
if ( fp == NULL )
|
||||
{
|
||||
perror("fopen");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
size = fread(input, 1, INPUT_SIZE, fp);
|
||||
|
||||
if ( ferror(fp) )
|
||||
{
|
||||
perror("fread");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( !feof(fp) )
|
||||
{
|
||||
printf("Input too large\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( fp != stdin )
|
||||
{
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
LLVMFuzzerTestOneInput(input, size);
|
||||
}
|
||||
|
||||
size = fread(input, 1, INPUT_SIZE, fp);
|
||||
|
||||
if ( ferror(fp) )
|
||||
{
|
||||
perror("fread");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( !feof(fp) )
|
||||
{
|
||||
printf("Input too large\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( fp != stdin )
|
||||
{
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
LLVMFuzzerTestOneInput(input, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||