Skip to content

Functions with std::string/std::list parameters are never instrumented by LLVM backend #1927

@Teemperor

Description

@Teemperor

IMPORTANT

  1. You have verified that the issue to be present in the current dev branch.
  • ye
  1. Please supply the command line options and relevant environment variables,
    e.g., a copy-paste of the contents of out/default/fuzzer_setup..
  • not even starting the fuzzer, N/A

Describe the bug
If a function contains a std::string/std::list parameter (or template class referencing those types), the function is not instrumented.

To Reproduce
Steps to reproduce the behavior:

  1. Build AFL++. The system compiler should use libstdc++ by default (which is the case on most linux distros).
  2. Create the following file:
#include <cstdio>
#include <string>

#ifdef I_WANNA_DIE
typedef std::string Param;
#else
typedef int Param;
#endif

int g;

void func(Param p) {
  if (g) { // this probably should create coverage...
    printf("foo");
  }
}
  1. Compile it with ./AFLplusplus/afl-clang-fast++ path/to/file.cpp to see AFL++ would instrument this.
  2. Run ./AFLplusplus/afl-clang-fast++ path/to/file.cpp -DI_WANNA_DIE=1 and it no longer instruments it.
$ ./AFLplusplus/afl-clang-fast++ what-the-fuck.cpp -o /dev/null -c
afl-cc++4.09a by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: LLVM-PCGUARD
SanitizerCoveragePCGUARD++4.09a
[+] Instrumented 3 locations with no collisions (non-hardened mode) of which are 0 handled and 0 unhandled selects.
$ ./AFLplusplus/afl-clang-fast++ -DI_WANNA_DIE=1 what-the-fuck.cpp -o /dev/null -c
afl-cc++4.09a by Michal Zalewski, Laszlo Szekeres, Marc Heuse - mode: LLVM-PCGUARD
SanitizerCoveragePCGUARD++4.09a
[!] WARNING: No instrumentation targets found.

Expected behavior
It probably should instrument the function.

Additional context
The function isIgnoreFunction in instrumentation/afl-llvm-common.cc contains the following code which seems to filter all these functions out because std::string is mangled as St7__cxx1112basic_string... with libstdc++ (the __cxx is the relevant substring).

  static constexpr const char *ignoreSubstringList[] = {

      "__asan", "__msan",       "__ubsan",    "__lsan",  "__san", "__sanitize",
      "__cxx",  "DebugCounter", "DwarfDebug", "DebugLoc"

  };

  for (auto const &ignoreListFunc : ignoreSubstringList) {

    // hexcoder: F->getName().contains() not avaiilable in llvm 3.8.0
    if (StringRef::npos != F->getName().find(ignoreListFunc)) { return true; }

  }

TLDR: Filtering based on whether function name contains __cxx is skipping everything that referenced std::string/list in the mangled name.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions