AFL icon indicating copy to clipboard operation
AFL copied to clipboard

error: unable to load plugin '../afl-llvm-pass.so': '../afl-llvm-pass.so: undefined symbol: _ZNK4llvm10ModulePass17createPrinterPassERNS_11raw_ostreamERKSs'

Open xukun311 opened this issue 5 years ago • 13 comments

hello, when i build afl to llvm_mode, creat some error. like below: ➜ llvm_mode make [] Checking for working 'llvm-config'... [] Checking for working 'clang'... [] Checking for '../afl-showmap'... [+] All set and ready to build. [] Building 32-bit variant of the runtime (-m32)... failed (that's fine) [*] Testing the CC wrapper and instrumentation output... unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=clang ../afl-clang-fast -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -DAFL_PATH="/usr/local/lib/afl" -DBIN_PATH="/usr/local/bin" -DVERSION="2.52b" ../test-instr.c -o test-instr error: unable to load plugin '../afl-llvm-pass.so': '../afl-llvm-pass.so: undefined symbol: _ZNK4llvm10ModulePass17createPrinterPassERNS_11raw_ostreamERKSs' make: *** [test_build] Error 1

============================= my llvm verion is : ➜ llvm11 llvm-as --version LLVM (http://llvm.org/): LLVM version 11.0.0git Optimized build with assertions. Default target: x86_64-unknown-linux-gnu Host CPU: cascadelake ➜ llvm11 clang --version clang version 11.0.0 Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/local/llvm11/bin ➜ llvm11

xukun311 avatar Jul 09 '20 07:07 xukun311

I ran into this as well.

docfate111 avatar Feb 11 '21 20:02 docfate111

its probably due because your clang is not the latest one. update your clang with

sudo apt install clang

HACKE-RC avatar Mar 24 '21 03:03 HACKE-RC

I am having the same problem on a Gentoo Linux installation. I have LLVM 12.0.0 installed and I'm still seeing the problem.

gemarcano avatar May 17 '21 06:05 gemarcano

I've been doing some investigation, and I'm also posting what I'm finding here in the Gentoo issue tracking this problem.

Looks like at least on my system a whole swath of LLVM symbols can't be resolved at build-time. A quick sample of two symbols:

ld.lld: error: undefined symbol: llvm::ModulePass::~ModulePass()
>>> referenced by afl-llvm-pass.so.cc:52
>>>               /tmp/afl-llvm-pass-8f42cb.o:((anonymous namespace)::AFLCoverage::~AFLCoverage())
>>> referenced by afl-llvm-pass.so.cc
>>>               /tmp/afl-llvm-pass-8f42cb.o:(vtable for (anonymous namespace)::AFLCoverage)

ld.lld: error: undefined symbol: llvm::Type::getInt8Ty(llvm::LLVMContext&)
>>> referenced by afl-llvm-pass.so.cc:77
>>>               /tmp/afl-llvm-pass-8f42cb.o:((anonymous namespace)::AFLCoverage::runOnModule(llvm::Module&))

gemarcano avatar May 17 '21 07:05 gemarcano

My llvm and clang installations seem fine otherwise, as I can build other applications using clang, and LLVM is working fine as I can build and use rust just fine with the system llvm.

gemarcano avatar May 17 '21 07:05 gemarcano

Even if most of the symbols I found that are missing are somehow loaded at runtime, it still appears that createPrinterPass isn't found.

Here's the build output with verbose output:

# unset AFL_USE_ASAN AFL_USE_MSAN AFL_INST_RATIO; AFL_QUIET=1 AFL_PATH=. AFL_CC=clang ../afl-clang-fast -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -DAFL_PATH=\"/usr/lib64/afl\" -DBIN_PATH=\"/usr/bin\" -DVERSION=\"2.57b\"  ../test-instr.c -o test-instr -v -fuse-ld=lld
clang version 12.0.0
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm/12/bin
Selected GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
Found CUDA installation: /opt/cuda, version 11.0
 "/usr/lib/llvm/12/bin/clang-12" -cc1 -triple x86_64-pc-linux-gnu -emit-obj --mrelax-relocations -disable-free -disable-llvm-verifier -discard-value-names -main-file-name test-instr.c -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -v -resource-dir /usr/lib/llvm/12/bin/../../../../lib/clang/12.0.0 -D _FORTIFY_SOURCE=2 -D "AFL_PATH=\"/usr/lib64/afl\"" -D "BIN_PATH=\"/usr/bin\"" -D "VERSION=\"2.57b\"" -D __AFL_HAVE_MANUAL_CONTROL=1 -D __AFL_COMPILER=1 -D FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1 -D "__AFL_LOOP(_A)=({ static volatile char *_B __attribute__((used));  _B = (char*)\"##SIG_AFL_PERSISTENT##\"; __attribute__((visibility(\"default\"))) int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); _L(_A); })" -D "__AFL_INIT()=do { static volatile char *_A __attribute__((used));  _A = (char*)\"##SIG_AFL_DEFER_FORKSRV##\"; __attribute__((visibility(\"default\"))) void _I(void) __asm__(\"__afl_manual_init\"); _I(); } while (0)" -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm/12/bin/../../../../lib/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wall -Wno-pointer-sign -fdebug-compilation-dir /tmp/portage/app-forensics/afl-2.57b/work/AFL-2.57b/llvm_mode -ferror-limit 19 -funroll-loops -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -load ../afl-llvm-pass.so -o /tmp/test-instr-8f1575.o -x c ../test-instr.c
error: unable to load plugin '../afl-llvm-pass.so': '../afl-llvm-pass.so: undefined symbol: _ZNK4llvm10ModulePass17createPrinterPassERNS_11raw_ostreamERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE'

Demangling the symbol:

llvm::ModulePass::createPrinterPass(llvm::raw_ostream&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const

gemarcano avatar May 17 '21 07:05 gemarcano

Interesting, if I try building the plugin manually but add -lLLVM-12 to the command, the only symbol missing is:

ld.lld: error: undefined symbol: llvm::PassManagerBuilder::addGlobalExtension(llvm::PassManagerBuilder::ExtensionPointTy, std::__1::function<void (llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&)>)
>>> referenced by PassManagerBuilder.h:244 (/usr/lib/llvm/12/include/llvm/Transforms/IPO/PassManagerBuilder.h:244)
>>>               /tmp/afl-llvm-pass-dc9876.o:(llvm::RegisterStandardPasses::RegisterStandardPasses(llvm::PassManagerBuilder::ExtensionPointTy, std::__1::function<void (llvm::PassManagerBuilder const&, llvm::legacy::PassManagerBase&)>))

ld.lld: error: undefined symbol: llvm::ModulePass::createPrinterPass(llvm::raw_ostream&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const
>>> referenced by afl-llvm-pass.so.cc
>>>               /tmp/afl-llvm-pass-dc9876.o:(vtable for (anonymous namespace)::AFLCoverage)
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)

So it looks like for some reason this symbol is not in LLVM-12???

EDIT: Hm, looks like a second symbol is missing also for some reasonm addGlobalExtension.

gemarcano avatar May 17 '21 08:05 gemarcano

tried updating your clang?

HACKE-RC avatar May 18 '21 03:05 HACKE-RC

My clang is at latest, I think, at 12.0.0.

gemarcano avatar May 18 '21 03:05 gemarcano

Interesting. I did find a library in the LLVM system directory with a similar symbol defined, but it's not the same... here's the symbol (and its demangled version) that's being asked for by afl:

_ZNK4llvm10ModulePass17createPrinterPassERNS_11raw_ostreamERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE
llvm::ModulePass::createPrinterPass(llvm::raw_ostream&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const

And here's the symbol I found in my system LLVM:

_ZNK4llvm10ModulePass17createPrinterPassERNS_11raw_ostreamERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@LLVM_12
llvm::ModulePass::createPrinterPass(llvm::raw_ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const@@LLVM_12

Hm, looks like the difference is C++11 string linking? and the @@LLVM_12 tag.

gemarcano avatar May 18 '21 03:05 gemarcano

After investigating a bit more what the sources of those namespaces are, turns out that what appears to be happening is that my LLVM links against libstdc++ while clang by default tries to link against libc++. If I force clang to use libstdc++ when building afl, I'm no longer getting missing symbols. I think this is a consequence of AFL trying to build an out-of-tree pass for LLVM, and not knowing how LLVM was built. I'm not exactly sure how to go about fixing this.

gemarcano avatar May 18 '21 04:05 gemarcano

Before you start your own afl fork, just switch to https://github.com/aflplusplus/aflplusplus Alternatively, there are probably working docker files around with prior clang versions

domenukk avatar May 18 '21 08:05 domenukk

I did some experimentation last night, and I can get AFL to build if I disable Gentoo's clang support for linking against libc++ by default. But I'll likely switch to aflplusplus anyway (just found out about it last night) which builds just fine regardless (at least on Gentoo).

gemarcano avatar May 18 '21 14:05 gemarcano