Ensuring Code Safety Without Runtime Checks for Realtime






















- Slides: 22
Ensuring Code Safety Without Run-time Checks for Real-time Control Systems -Presented by Sumant Kowshik Joint Work With Dinakar Dhurjati and Vikram Adve. University of Illinois at Urbana-Champaign Supported by NSF U. Illinois
Motivation Reliable online upgrade of control software. Control code upgrade can have n Timing errors n Logical errors n Runtime software faults n Violate memory safety. Bugs or attacks due to memory errors. n Platforms with limited address protection n Malicious upgrades compromise system and the framework for reliable upgrade. n Insider attacks: SANS/FBI report.
Motivation Reliable online upgrade of control software. Control code upgrade can have n Timing errors Simplex n Logical errors n Runtime software faults n Violate memory safety. Attacks disguised as upgrades. n Platforms with limited address protection n Malicious upgrades compromise system and the framework for reliable upgrade. n Insider attacks: SANS/FBI report.
Motivation II Memory safety: static checking? n Avoid run-time overhead n Early bug detection Static checking for general languages difficult. Impose restrictions on the language – Control-C Rationale: Structure of control code n Computationally intensive, use dense arrays n Simple data structures, dynamic memory. n Mostly in C.
Related work What’s wrong with existing solutions? n Java, RT-Java, Ccured, Safe-C etc. w Runtime checks w Garbage collection Current Alternatives n Vault [PLDI 01], Cyclone[PLDI 02] w Target general applications w Annotations: cumbersome. w Runtime checks. Complementary techniques n n Proof carrying code: compiler untrusted. Vault, Engler et al [OSDI 00], Wagner et al. w Checking library code.
Contributions of control-C Targets embedded/control code. 100% static checking to guarantee safety. Easy portability: As close to C as possible. Novel language features n Region-based dynamic memory: single region active at a time. n Array sizes, index expressions and loop bounds affine expressions. Trade-off : expressiveness for control codes vs. safety checking compiler technology vs. portability.
Outline of Talk Introduction Context n n System assumptions Attacks. Language rules Implementation Results
The system http: //www-rtsl. cs. uiuc. edu/drii/download upgrade Simplex Safety cont. output Decision logic input Catch runtime, logical and timing errors n Kicks out the offending controller. Stack overflow detected. Accesses to a range of reserved addresses n Eg. Linux – high gigabyte (1 GB of 4 GB) reserved
Unsafe code Fatal memory errors can be due to v Variable referencing memory outside the bounds of its data type. v Bad casting, pointer arithmetic, uninitialized pointers v Array bounds violation v Use of pointer to freed memory. v Example: char killcode[] = “x 55x 89…xc 3x 90”; void control. Func(float a, float b) { int *ret = (int *)&ret + 2; *ret = killcode; } n n Jumps in the code to data areas/non-code areas. Calls to unknown functions.
Control-C – Basic Issues Start with C No syntactic changes, only usage changes. Basic issues. n Type safety. w No casts involving pointers. w No pointer arithmetic. w Scalar pointers need to be initialized explicitly before being dereferenced or before taking their address.
Control-C – Dynamic Memory Problem : Pointers to freed memory. Solution : Region-based memory allocation Define RInit, RFree, RMalloc n No explicit free call Single region active at a time. All local and global scalar pointers dead at region free. n
Example – Region Usage Legal Code Illegal Code if(cond) { RInit(); t = 4; } else { RInit(); t = 8; } p = RMalloc(t); RFree(); … int *p, **t; RInit(); p = RMalloc(4 * sizeof(int)); Multiple regions RInit(); active … RFree(); Pointer p not t = &p; dead after RFree func(**t); Potentially
Control-C – Array indexing. Problem : Checking for array bounds n n Index expression must evaluate to a value within array bounds Difficulty: Analysis of constraints on symbolic integer expressions. Solution : n n Loop bounds affine w. r. t. array size Index expression affine w. r. t loop index variables or the size of array.
Example – Legal Array Usage extern M, N; int * generate(int *B, int n) { main() { int *A, i, j, k, ; … if (B[n] > 0) { if (( N > 0) && (N < 5)) { A = (int *) RMalloc(5 * B[n] + 10); B = (int *)RMalloc(N * 30); for (i=M; i < B[n]+M ; ++i) { intialize(B); j = i - M; C = generate(B, 20); k = j * 4; } A[k] = j ; } } … } Interprocedural propagation Array sizes not constant. Symbolic constant M cancels out
Control-C : Aggregate Types Problem : Analysis of pointers in aggregate types (structs, arrays). Solution : Use of pointers to freed memory n Structs or arrays containing pointers must be allocated dynamically using malloc or alloca. Solution : Initialization n Initializing pointers to base of reserved address range. Thus, we can have arbitrary pointerbased data structures and arrays.
Outline of Talk Introduction Context n n System assumptions Attacks. Language rules Implementation Results
Implementation LLVM compiler framework n n http: //llvm. cs. uiuc. edu Things gotten for free w Source language independence w Type safety (except for cast) w Jumps to code locations only. w Link-time interprocedural analysis + separate compilation. w SSA.
Control-C Compiler Features Pointers n Global dataflow analysis ensuring that all pointers are initialized Array bounds analysis n Interprocedural constraint propagation for bounds checking. Regions n Liveness analysis of pointers upon RFree.
Results Application Platform Lines Dyn memory Arrays Ptrs Changed Pendulum Linux 300 No Yes No 0 Pendubot Windows 1300 Yes Yes 35 Tiny. OS Linux 300 No Yes 0 v v Language expressive enough for control? How easy is it to port from C? v Pointer arithmetic replaced by index variable array traversal v Dynamic memory: use regions v Unions with pointers need to be split
Results II Restrictions detect all potential attacks? n Simplex: Inverted pendulum w Uninitialized pointers w Pointer arithmetic w Illegal casts w Array overflow.
Conclusions and Future Work Control-C aims at guaranteeing absolute safety using static checking alone The language is close to C and is expressive enough for control/embedded applications Future work n n n Expand the scope of the language Detect illegal system calls/illegal sequences of system calls Formally verifying that control-C guarantees memory safety
Merci Beaucoup!