about summary refs log tree commit diff
path: root/instrumentation/afl-llvm-common.cc
diff options
context:
space:
mode:
authorJonathan Neuschäfer <j.neuschaefer@gmx.net>2023-04-10 12:22:42 +0200
committerJonathan Neuschäfer <j.neuschaefer@gmx.net>2023-04-10 13:47:19 +0200
commit9e3e1a5512acd44020430f24c9ec1260aeeda285 (patch)
treec4baa6c4a7721658171dadfdf8b76d799bab1140 /instrumentation/afl-llvm-common.cc
parent0911525194f4a9d40fcb65e0ab7a83ccf661c192 (diff)
downloadafl++-9e3e1a5512acd44020430f24c9ec1260aeeda285.tar.gz
afl-cc: Don't offer __AFL_INIT() etc. in GCC/CLANG modes
instrumentation/README.persistent_mode.md documents in the section about
deferred forkserver initialization:

> With the location selected, add this code in the appropriate spot:
>
> ```c
> #ifdef __AFL_HAVE_MANUAL_CONTROL
>   __AFL_INIT();
> #endif
> ```
>
> You don't need the #ifdef guards, but including them ensures that the program
> will keep working normally when compiled with a tool other than afl-clang-fast/
> afl-clang-lto/afl-gcc-fast.
>
> Finally, recompile the program with afl-clang-fast/afl-clang-lto/afl-gcc-fast
> (afl-gcc or afl-clang will *not* generate a deferred-initialization binary) -
> and you should be all set!


This strongly implies that you can compile a program that uses __AFL_INIT()
under an `#ifdef __AFL_HAVE_MANUAL_CONTROL` guard with afl-gcc/-clang.

However, this currently fails:

  $ cat example.c
  #include <stdio.h>

  int main(void) {
  #ifdef __AFL_HAVE_MANUAL_CONTROL
  	__AFL_INIT();
  #endif

  	puts("Hello");
  }
  $ afl-gcc example.c -o example
  afl-cc++4.06a by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: GCC-GCC
  [!] WARNING: You are using outdated instrumentation, install LLVM and/or gcc-plugin and use afl-clang-fast/afl-clang-lto/afl-gcc-fast instead!
  afl-as++4.06a by Michal Zalewski
  [+] Instrumented 1 locations (64-bit, non-hardened mode, ratio 100%).
  /usr/bin/ld: /tmp/ccuJHcpt.o: in function `main':
  /home/jn/dev/fuzz/AFLplusplus/example.c:5: undefined reference to `__afl_manual_init'
  collect2: error: ld returned 1 exit status


The issue here is an inconsistency in afl-gcc (i.e. afl-cc operating in GCC mode):

 - afl-cc defines __AFL_HAVE_MANUAL_CONTROL and __AFL_INIT unconditionally
 - __AFL_INIT relies on __afl_manual_init, which is defined in afl-compiler-rt.o
 - afl-cc doesn't link afl-compiler-rt in GCC or CLANG mode


Since afl-gcc/-clang is documented as not supporting deferred forkserver
initialization, this patch omits the definitions of __AFL_HAVE_MANUAL_CONTROL
and related macros in GCC/CLANG mode.

This restores the ability to compile a deferred-forkserver program under
afl-gcc, if it can also be compiled under gcc.

[ In case someone reads this an feels adventurous enough (as I did) to
  think about enabling deferred forkserver under afl-gcc: Whether the
  deferred forkserver actually works can be verified by placing a
  usleep(100000) or similar at the start of main (before __AFL_INIT()),
  and watching the execution speed. It doesn't work. ]
Diffstat (limited to 'instrumentation/afl-llvm-common.cc')
0 files changed, 0 insertions, 0 deletions