LLVM

The LLVM Undefined Behavior Sanitizer

This post contains the steps and commands to setup, build and run Undefined Behavior Sanitizer on a small C example. We also do a customary investigation into the LLVM IR generated for different UBSan instrumentations and compare them at a high level.

Environment Setup

Build the following LLVM projects in order to obtain the binaries required to run UBSan:

  1. clang
  2. clang-tools-extra
  3. compiler-rt

LLVM Build Command

cd llvm-project mkdir build; cd build; cmake -G 'Ninja' -DLLVM_ENABLE_PROJECTS='clang;clang-tools-extra;compiler-rt' -DCMAKE_INSTALL_PREFIX=./ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=$(which gcc) -DCMAKE_CXX_COMPILER=$(which g++) -DCMAKE_C_FLAGS=-fdump-rtl-expand -DLLVM_ENABLE_DOXYGEN=false -DLLVM_OPTIMIZED_TABLEGEN=True -DLLVM_ENABLE_WERROR=OFF ../llvm ninja all

Setup

export PATH=/llvm-project/build/bin/:$PATH         </kbd>

Testcase

The following testcase assigns the address 0 to an integer pointer during declaration. Then it dereferences the pointer to assign the value at that location to another integer variable. This would result in a segmentation fault. testcase

UBSan Minimal Runtime

Compilation with Instrumentation

clang -o ubsan_min_exe main.c -fsanitize=undefined -fsanitize-minimal-runtime -O1

Execution

./ubsan_min_exe

Output

ubsan: type-mismatch 4202536

UBSan Full Runtime

Compilation with Instrumentation

clang -o ubsan_full_exe main.c -fsanitize=undefined -O1

Execution

./ubsan_full_exe

Output

main.c:5:13: runtime error: load of null pointer of type 'int' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior main.c:5:13 in 589032128

Compilation with instrumentation & support to print symbolized stack traces for errors

clang -o ubsan_full_exe main.c -fsanitize=undefined -O1 -g -fno-omit-frame-pointer

Execution

./ubsan_full_exe

Output

main.c:5:13: runtime error: load of null pointer of type 'int' #0 0x433c5f in main /repo/emkasuu/test/ubsan/example/main.c:5:13 #1 0x7f437c372554 in __libc_start_main (/lib64/libc.so.6+0x22554) #2 0x402b6a in _start (/repo/emkasuu/test/ubsan/example/ubsan_full_exe+0x402b6a)

Examine the LLVM IR

LLVM IR (without UBSan enabled)

clang -o IR main.c -O1 -S -emit-llvm

IR

IR

UBSan Minimal Runtime

clang -o minIR main.c -fsanitize=undefined -fsanitize-minimal-runtime -O1 -S -emit-llvm

IR (Minimal Runtime)

Minimal Runtime IR

UBSan Full Runtime

clang -o fullIR main.c -fsanitize=undefined -O1 -S -emit-llvm

IR (Full Runtime)

Full Runtime IR

Comparing the IR’s

Normal IR vs UBSan Minimal Runtime IR

Normal IR vs Minimal Runtime IR

UBSan Minimal Runtime IR vs Full Runtime IR

Minimal Runtime IR vs Full Runtime IR

Previous Post in LLVM

Discussion & Comments