SoftBound: Highly Compatible and Complete Spatial Memory Safety for C

Reference:

Background

spatial violation detection and prevention.

Object-Based Approaches.

Pointer-Based Approaches.

Comparison of Various Approaches.

Comparison of representative object-based and pointer-based approaches

Design

Associates base and bound metadata with every pointer.

Disjoint metadata representation avoids memory layout changes and arbitrary casts.

Metadata Propagation with Function Calls.

  • When pointers are passed as arguments or returned from functions, their base and bound metadata must also travel with them.
  • If all pointer arguments were passed and returned on the stack (i.e., via memory and not registers), the above table-lookup approach for handling in-memory metadata would suffice.
  • However, when passed via registers:
    • use procedure cloning [^c12] to transform every function declaration and function call site to include additional arguments for base and bound.
    • the function name is appended with a SoftBound-specific unique identifier, specifying this function has been transformed by SoftBound.
  • For variable argument functions:
    • extended with two more parameters:
    • the number of parameters passed (in bytes)
    • the number of pointers passed (and thus the number of extra base/bound arguments passed to the function)

Implementation

Instrumentaton

The SoftBound pass inserts code to:1

  1. Create a base and bound value for each pointer non-memory value in the program;
  2. perform base/bound metadata manipulation prior to every memory operation that reads or writes a pointer;
  3. perform a bound check before memory operation;
  4. rewrite all function calls to pass the base and bounds.

Global Variables

Memcpy()

Function pointers

Creating pointers from integers

Arbitrary Casts and unions

Redundant elimination

To eliminate some obviously redundant checks of the same pointer, our prototype performs a simple intra-procedural dominator-based redundant check elimination. These transformations are all strictly local (intra-procedural) transformations, without any whole program type inference or alias analysis.

Calls to external functions (i.e. any library function that has not been SoftBound transformed) are mapped to wrapper functions.

SoftBound uses standard C functions to implement the code to access the base/bound metadata and to perform the bounds checks. The SoftBound pass invokes these routines by inserting appropriate function calls that are later forcibly inlined by subsequent LLVM passes.

Metadata Implementation

Two implementations: a hash table and a tag-less shadow space.

Hash Table:

  • Each entry: a three tuple: (tag, base, bound)

    • 64-bit pointers, each entry is 24 bytes.
  • Hash function: the double-word address modulo the number of entries in the table.

    • simple shift-and-mask operation. (with num of entries in the table is power of 2.)
  • 9 x86 instructions for the lookup.

Shadow Space:

  • a large enough table in the virtual address space.
  • 5 x86 instructions for the lookup.

Evaluation

Overhead:

67% full checking;

22% store-only checking.

Compiler: LLVM 2.4

Benchmark:

  • a testbed for buffer overflow attacks RIPE;
  • real programs with spatial errors: go, compress, gzip, polymorph.
  • SPECint, SPECfp, Olden.

Comparison:

  • Valgrind/memcheck, Valgrind/ptrcheck;
  • GCC Mudflap;
  • Jones and Kelly version of GCC;
  • CCured
  • MSCC

In general, better than MSCC, worse than CCured.

Not Complete for pointer protection:

  • memcpy(): infer whether the memory has pointers by looking at the type being copied at the call site – not foolproof;

  • functin pointers: base=bound=pointer, zero-sized object. can prevent data pointer to function pointer casting; but cannot prevent func to func casting;

  • no temporal.

Created Jul 23, 2019 // Last Updated Jul 17, 2021

If you could revise
the fundmental principles of
computer system design
to improve security...

... what would you change?