Skip to content
Snippets Groups Projects
  • Jonathan Neuschäfer's avatar
    9e3e1a55
    afl-cc: Don't offer __AFL_INIT() etc. in GCC/CLANG modes · 9e3e1a55
    Jonathan Neuschäfer authored
    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. ]
    9e3e1a55
    History
    afl-cc: Don't offer __AFL_INIT() etc. in GCC/CLANG modes
    Jonathan Neuschäfer authored
    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. ]
Code owners
Assign users and groups as approvers for specific file changes. Learn more.