1 of 1

BlankIt Library Debloating

Getting what you want instead of cutting what you don't

Problem

  • To unblank code, execution takes a trampoline to BlankIt’s probe_copy() function
  • Effective debloating of practical, commonly used libraries, e.g. glibc, libm, libgcc, libstdc++  which exhibit many CVEs
  • Huge security benefit : > 97% ROP gadget reduction, > 95% CVE function elimination
  • Significant improvement in the quality of gadgets: 15 out of 17 SPEC benchmarks show rank > 1, making resulting gadgets difficult to use
  • Protection of real world software: nginx and sshd
  • Practical solution : 18% runtime overhead on average

Chris Porter*, Girish Mururu*, Prithayan Barua, Santosh Pande

BlankIt

Decision tree-based call graph prediction

Execution flow

Results

Conclusion

“What’s a debloat?”

Compile-time Runtime

Everyone needs their libraries

    • Modern software relies heavily on them
    • Support a large amount of functionality, though only a small of amount of such functionality may get used
    • Ubuntu Desktop 16.04 user programs utilize only about 10% of the shared library functions

But libraries carry security vulnerabilities

    • Glibc is a mine of gadgets like ROP, JOP gadgets
    • Gadgets are code snippets that can be stitched together to create malicious programs via illegal control flow
    • Although known CVEs are patched, future attacks can be built over these gadgets

And state-of-the-art protection is imperfect

    • ASLR (address space layout randomization) and DEP (data execution prevention) are traditional mechanisms that cannot handle advanced return-to-libc attacks
    • CFI (control flow integrity) and CPI (code pointer integrity) cannot defend against CFB (control-flow bending) and other non control data attacks
    • CFI, CPI do not handle privilege escalation attacks
    • New attacks undermine the current best defense practices

foo

Lib.foo()

Predict & Link

De-Link/Blank

Partial call graph of foo()

Compared with…

Piecewise (Quach et al., 2018)

    • musl libc, and requires source
    • 79-86% code reduction, 71% gadget reduction

Chisel (Heo et al., 2018)

    • programmer-provided spec of desired functionality
    • reinforcement learning loop: cut, test, learn → reduced program
    • 66% gadget reduction, removes several CVEs

RAZOR (Qian, Hu, et al., 2019)

    • 70% code debloated
    • heuristics to infer code to debloat

Goal of prediction: Distinguish legitimate and illegitimate dynamic control-flow

Features:

    • Reverse Dominance Frontiers (RDFs) of every argument
    • Argument values decide the control-flow within lib functions
      • E.g. sqrt(x), exp(x) depend on range of x
    • Call site and callee name

--Debloating is about downsizing the amount of code and gadgets available for constructing an attack.

Takeaways

SPEC CPU 2006 (CPU-bound benchmark suite, glibc-heavy)

    • 18% runtime overhead
    • 94% prediction accuracy
    • 97% ROP gadget reduction

nginx

    • 10% max runtime overhead
    • 100% prediction accuracy
    • 99% ROP gadget reduction

sshd

    • negligible runtime overhead
    • 95% prediction accuracy
    • 98% ROP gadget reduction

SPEC Runtime Performance

  • Execution flows along some path in the call graph at runtime
  • The BlankIt framework predicts and links only the needed library code at each library call site
  • It delinks it after use
  • The predict and blank steps happen together
  • When BlankIt predicts the next library call, it blanks the previous library functions that were copied into memory

Unblank

Predict and blank

PLDI ’20, June 15–20, 2020, London, UK