Skip to content

CMPT 416 Project (Custom Clang Checker for systemd)

Notifications You must be signed in to change notification settings

SamanthaYu/CacheChecker

Repository files navigation

CacheChecker

  • CacheChecker detects cache-based use-after-frees within systemd
  • In this repo, we demonstrate how to create a custom Clang static analyzer checker

Setup

How to Build Clang

  • There's two ways to build Clang: Use CMake or use Ninja
  • We recommend building with Ninja, because it will only build the changed files
    • Compared to CMake which takes 2 hours for every build, Ninja can compile a checker within 5 minutes

Approach 1: Use CMake

  • Create a build directory inside llvm-project: mkdir build
  • Execute inside the build directory: cmake -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" -DLLVM_USE_LINKER=gold ../llvm
    • -DLLVM_ENABLE_PROJECTS=clang: To build Clang
    • -DCMAKE_BUILD_TYPE=Release: To build in release mode instead of debug mode (much faster)
    • -DLLVM_USE_LINKER=gold: To use the gold linker, which is much faster than ld
  • Run: make
    • This step takes about 2 hours
    • Every time that we make a change to a Clang checker, we would have to re-build the whole project again

Approach 2: Use Ninja

  • Create a build directory inside llvm-project: mkdir build
  • Execute inside the build directory: cmake -G Ninja -DLLVM_ENABLE_PROJECTS=clang -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release ../llvm
    • Unlike the CMake attempt, we don’t recommend using the gold linker, because we ran into an internal error towards the end of compilation
  • ninja
    • Like CMake, this step initially takes about 2 hours
    • While building, users should be careful that their CPU will not run out of memory as Ninja can easily consume all available memory
    • Since Ninja builds incrementally, users can stop the build process at any time and resume it

Environment Variables

  • Add the following environment variables:
    • /llvm-project/build/bin
    • /llvm-project/clang/include
    • /llvm-project/llvm/include

How to Use a Custom Clang Checker

  • Pull this CacheChecker repo into /llvm-project/clang and re-build Clang
  • There's two ways to use a Clang custom checker: Use LLVM's load-plugin argument or use CodeChecker
  • For our cache checker, we need a static analysis that can perform CTU (cross-translation unit) analysis

Register the Checker

Approach 1: Use LLVM's load-plugin Argument

  • The Clang documentation usually describes creating a custom checker within the source build only
  • It’s possible to use an out-of-source checker by using the load-plugin argument:
    • e.g. If SimpleStreamChecker is our out-of-source checker, we can execute inside systemd's build directory: scan-build -load-plugin SimpleStreamChecker/libSimpleStreamChecker.so -enable-checker alpha.SimpleStreamChecker ninja -C build
  • With the load-plugin argument, users must still register the checker in clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  • The reasoning behind using the load-plugin argument is to avoid having to rebuild Clang every time that we want to build the checker
    • With Ninja, we would only be incrementally building our changes, so placing the checker in the LLVM source tree is still reasonable

Approach 2: Use CodeChecker

  • CodeChecker passes arguments back to the Clang static analyzer
    • However, CodeChecker does not currently support the load-plugin argument, so we build the custom checker in the source tree
  • Collect the cross-translation units: CodeChecker analyze compile_commands.json -o /systemd-csa -ctu-collect -analyzers clangsa
    • compile_commands.json is the compilation database for systemd generated by meson build, because CacheChecker is designed to analyze systemd
    • We write the files to the directory /systemd-csa
  • Run Clang checkers: CodeChecker analyze compile_commands.json -o /systemd-csa -ctu-analyze -analyzers clangsa -enable alpha -disable alpha.security.taint
    • To reduce the amount of time spent analyzing the source code, we can use a compile_commands.json that only includes the translation units that we want to analyze
    • -enable alpha: Alpha checkers are disabled by default. We registered our cache checker as an alpha checker, so we have to enable all the alpha checkers
    • -disable alpha.security.taint: To run our checker on systemd, we had to disable the alpha.security.taint checker
  • Parse the results: CodeChecker parse /systemd-csa -e html -o /systemd-csa/reports_html
    • -o /systemd-csa/reports_html: Write the files to /systemd-csa/reports_html

Results

  • This CacheChecker was designed to detect the asynchronous use-after-free in CVE-2020-1712
  • We created an example schedule of CVE-2020-1712 in SamanthaYu/systemd#1
  • Unfortunately, CVE-2020-1712 requires value taint analysis, but the Clang static analyzer does not support this feature

Tests

We created tests for this custom checker in SamanthaYu/systemd#1
Cache checker detecting a use-after-free in an example scenario

About

CMPT 416 Project (Custom Clang Checker for systemd)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published