SoftBoundCETS Users Guide

Written by Santosh Nagarakatte

Overview

The SoftBoundCETS transformation is a memory safety transformation that is a part of the SAFECode compiler, which is a memory safety compiler built using the LLVM Compiler Infrastructure and the Clang compiler driver. A memory safety compiler is a compiler that inserts run-time checks into a program during compilation to catch memory safety errors at run-time. Such errors can include buffer overflows, invalid frees, and dangling pointer dereferences.

This manual will show how to compile programs with SoftBoundCETS and how to read the diagnostic output when a memory safety error occurs.

Compiling a Program with SoftBoundCETS

The easiest way to use SoftBoundCETS is to use the modified version of Clang that comes in the SAFECode distribution. Alternatively, the whole program analysis version of SoftBoundCETS can be downloaded from the SoftBoundCETS website. Transforms are performed transparently by the Clang compiler.

To compile programs with SoftBoundCETS memory safety transformation, add the -fsoftbound command-line option to the Clang command line:

You may also need to add a -L$PREFIX/lib option to the link command-line to indicate where the libraries are located; $PREFIX is the directory into which SAFECode was installed:

To configure an autoconf-based software package to use SoftBoundCETS in the SAFECode distribution, do the following:

  1. Set the environment variable CC to $PREFIX/clang.
  2. Set the environment variable CXX to $PREFIX/clang++.
  3. Set the environment variable CFLAGS to "-g -fsoftbound "
  4. Set the environment variable LDFLAGS to "-L$PREFIX/lib" where $PREFIX is the directory into which SAFECode was installed.
  5. Run the configure script
  6. Type "make" to compile the source code.
Note that some configure scripts may not use the LDFLAGS variable properly. If the above directions do not work, try setting CFLAGS to "-g -fsoftbound -L$PREFIX/lib".
Sample Debugging with SoftBoundCETS in SAFECode Distribution

Let's say that we have the following C program:

  1 #include "stdio.h"
  2 #include "stdlib.h"
  3 
  4 int
  5 foo (char * bar) {
  6   for (unsigned index = 0; index < 10; ++index)
  7     bar[index] = 'a';
  8   return 0;
  9 }
 10 
 11 int
 12 main (int argc, char ** argv) {
 13   char * array[100];
 14   int max = atoi (argv[1]);
 15 
 16   for (int index = max; index >= 0; --index) {
 17     array[index] = malloc (index+1);
 18   }
 19 
 20   for (int index = max; index >= 0; --index) {
 21     foo (array[index]);
 22   }
 23 
 24   exit (0);
 25 }

Lines 16-18 allocate character arrays of decreasing size, starting with the argument plus one specified by the user down to an array of one character. Lines 20-22 then call the function foo() which accesses elements 0-9 of the array.

If we compile this program with SoftBoundCETS within the SAFECode compiler and execute it:

We'll get the following error report:


In Store Dereference Check, base=0x60c050, bound=0x60c052, ptr=0x60c052, size_of_type=1, ptr+size=0x60c053

Softboundcets: Bounds violation detected

Backtrace:
./test.out[0x4058fc]
./test.out[0x405e83]
./test.out[0x404f0d]
./test.out[0x40563a]
./test.out[0x405a45]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x7fcecaa70bfd]
./test.out[0x404c99]


Aborted

The first thing to note is the error type. SoftBoundCETS is reporting a spatial safety violation with a store operation, meaning that some store is trying to access a memory location that it should not. The value of the pointer is 0x60c052. The size of the access is of one byte. The bounds of the object that the pointer points to is [0x60c050, 0x60c52). Debugging the code in gdb reveals that the out-of-bound memory access occurs in function foo.