Docstoc

Robustness Wrappers - Zhen Xiao

Document Sample
Robustness Wrappers - Zhen Xiao Powered By Docstoc
					An Automated Approach for Software
      Reliability and Security

                 Zhen Xiao
       Senior Technical Staff Member
           AT&T Labs – Research
       Joint work with Christof Fetzer
                    Motivation
• Software reliability is becoming increasingly
  important.
   – Financial transactions, virtual office environment, life
     critical applications, etc.
• Does the software function correctly under
  exceptional or stressful settings?
   – Field experience indicates that the error handling paths
     in the software typically contain most bugs.
   – Testing all boundary conditions before the official
     release of the software can be prohibitively expensive.
   Example: Robustness Violation
strcpy(destination, source)

source length


  destination     unmapped pages


                detectable with
                help of signal handler
                 Security Problems
strcpy(dst, attack_string)

attack_string length


     destination       shell script
                       attack code



We want to avoid all buffer overwrites!
                       Why C/C++?
                 Sourceforge Projects 10/18/2000
                  (8,296 open source projects)




        Other                                        Java
        41%                    C                     Other
                              27%          C++
                           C/C++           21%       C
                            48%                      C++

                Java
                11%



What is a good approach for increasing software reliability?
                    Challenges
• Transparency
   – Cannot assume access to the source code for
     applications & libraries.
• Cost effectiveness & scalability
   – Large number of applications, shared libraries, and
     functions.
   – Applications and libraries may change often.
• Flexibility
   – Different applications may need different levels of
     protection
Most Popular Libraries
Distribution of #Libraries vs. #Applications
                 Linux SuSE 8.0

Number of shared libraries                                   933
Number of applications                                 15431
Number of undefined func/appl                                ~49


  Automation is essential for protecting a large number of
  libraries and applications!
       The HEALERS Approach
• Fault-containment wrappers
   – Intercept function calls into the dynamic link libraries.
   – Provide transparent protection for software without
     source code access.
• Automated fault-injection experiments
   –   Find all functions defined in a library
   –   Detect arguments that cause a function to crash
   –   Derive safe argument types for each function.
   –   Prevent heap and stack buffer overflows and a large set
       of robustness violations.
The HEALERS Approach (Cont’d)
• Micro-generator architecture
   – Generate a variety of wrappers through a set of micro-
     generators.
   – Applications only pay the overhead they actually need.
Extracting Libraries and
 Undefined Functions
     Example: Unix Wrappers
• Overwrite “exit” by “abort”
• Wrapper:
  void exit(int status) { abort(); }
• Start wrapper:
  > setenv LD_PRELOAD `pwd`/wrapper.so
• No need to change existing programs!
  > date
  Wed Oct 18 13:06:41 EDT 2000
  Abort
Approach: Wrap Functions

                   calls
Application   strcpy(d,s)
              strcpy(d,s)   check d and s
 Wrapper
                   calls
 Shared
              strcpy(d,s)
 Library
       Keeping Track of the Heap
 Wrap malloc, calloc, realloc, free
 Use Red/Black trees to keep meta-data for each
  allocated block
   – Update Red/Black tree whenever such a function is called
   – Red/Black node contains address range of each block
• Check if the destination buffer is sufficiently large:
   – Search Red/Black tree to find pointer
   – returns #bytes between pointer and the end of the block
• Complexity:
   – Insert, Remove, Find: O(log(entries))
Wrapper Structure
             Original Function
 Wrapper needs to call the “original” function
 Access to original function by “dlsym”
 Example:
  – dlsym(RTLD_NEXT, “strcpy”);
  – returns address of original “strcpy” function
Wrapper Structure
          Wrapper Generation Process


Shared     Fault-Injection   Function          Wrapper
                                                            Wrapper
Library    Experiments       Specification     Generation




               Phase 1:                      Phase 2:
               Function Spec.                Wrapper
               Generation                    generation
  Run-time checks [SRDS2001]
• Example: function asctime(d)
  – wrapper checks that d is buffer of sufficient
    size
  – if not, return error code
  – otherwise, call original function
         Asctime Wrapper
char* asctime (const struct tm* a1) {
  char* ret;
  if (!check_R_ARRAY_NULL(a1,44)) {
     errno = EINVAL ;
     ret = (char*) (nil);
     goto PostProcessing;
  }
  asm("movl %ebp,%esp");
  asm("popl %ebp");
  asm("jmp *libc_asctime_0");
PostProcessing: ;
  return ret;
}
Function Specification for asctime
<function>
 <name>asctime</name>
 <argument>const struct tm*
  <robust_type>R_ARRAY_NULL[44]</robust_type>
 </argument>
 <return_type>char *</return_type>
 <error_value>NULL</error_value>
 <errors>
  <errno>EINVAL</errno>
 </errors>
 <attribute>unsafe</attribute>
</function>
Robust Argument Type
Generation of Function Specifications

                       Fault-     Function
Header                Injector   Declaration
 Files
                       Fault-     Function
                      Injector   Declaration
Manual
Pages     Generator
                       Fault-     Function
                      Injector   Declaration
Shared                 Fault-     Function
Library               Injector   Declaration
         Generator Algorithm
For each function in library
1. Find prototype of function:
   •   Parse include files given in manual pages, or
   •   Parse all header files that might contain prototype
2. Generate fault-injector using prototype
   •   Define sequence of hypotheses
   •   Perform automated fault injection experiments to test
       each hypothesis
   •   Select non-rejected hypothesis
Prototype Extraction for glibc2.2
   "External": no     "External":
     prototype         prototype    prototype
       found             found        found
        3%                63%       with grep
                                       32%

                                            prototype
  "Internal"                                 found in
     34%                                      manual
                                               31%


               Total: 1278 global functions
                   Errors in Manual
                 430 of 840 functions in manual




1.4 10.5                               88.1




0%           20%             40%          60%            80%            100%

  No header file in manual   Wrong header file in man   Correct header file
 Computation of Robust Argument
             Types
• Ideal Goal: determine set of argument
  values that crash a function

         crash                   no crash


set of all argument values

           wrapper accepts these values, rejects others
       Idea Goal Not Realistic
• Revised Goal: Accurate but not necessarily
  complete checks:

         crash                   no crash


set of all argument values

           wrapper accepts these values, rejects others
                  Approach
• Divide argument value set in disjoint
  subsets




set of all argument values

         Fundamental Type
 Classify Fundamental Types Using
           Fault-Injections
• Divide argument values in disjoint subsets




  no value crashes f
  all values crash f          wrapper accepts these
  some values crash f         values, rejects others
   Example: Fixed Arrays
                  set of all argument values

   WONLY_FIXED    RW_FIXED

    RONLY_FIXED   UNMAPPED


RONLY_FIXED[1],      NULL       INVALID
RONLY_FIXED[2],
                   read only not mapped
RONLY_FIXED[3],
                       3
…
        asctime: injection results
• Crashes for all test cases in:
   –   RONLY_FIXED[i] for i < 44
   –   WONLY_FIXED[i] for any i
   –   RW_FIXED[i] for i < 44
   –   INVALID crashes
• Does not crash for test cases in:
   – RONLY_FIXED[i] for i >= 44
   – RW_FIXED[i] for i >= 44
   – NULL
             Type Hierarchy
• Need to be able to compute union of value
  sets
• Define type hierarchy:
  – fundamental types: value sets of any two
    fundamental types is non-overlapping
  – union types: value set of this type is the union
    of the value set of its “subtypes”
           Fixed Array Type Hierachy
                 UNCONSTRAINED


                     INVALID
  R_ARRAY_NULL[s]              W_ARRAY_NULL[s]
                       s≤t
     s≤t         RW_ARRAY_NULL[t]      s≤t

      R_ARRAY [t]                 W_ARRAY[t]
                    t≤u NULL     t≤u
     t≤v                               t≤v
                     RW_ARRAY [u]
RONLY_FIXED[v]                    WONLY_FIXED[v]
                           u≤v
                     RW_FIXED[v]
     asctime: Robust Argument Type
                 UNCONSTRAINED



  R_ARRAY_NULL[s]            W_ARRAY_NULL[s]
                       s≤t
     s≤t         RW_ARRAY_NULL[t]     s≤t

     R_ARRAY [44]                W_ARRAY[t]
                    44≤44       t≤u
     44≤v
                    RW_ARRAY [44]
RONLY_FIXED[v]
                          44≤v
                    RW_FIXED[v]
     asctime: Robust Argument Type
                 UNCONSTRAINED



  R_ARRAY_NULL[44]             W_ARRAY_NULL[s]
                       44≤44
     44≤44       RW_ARRAY_NULL[44]     s≤t

     R_ARRAY [44]                W_ARRAY[t]
                        NULL
                    44≤44       t≤u
     44≤v
                    RW_ARRAY [44]
RONLY_FIXED[v]
                          44≤v
                    RW_FIXED[v]
   Phase 2: Generation of Wrappers
                             Retry
                             Wrapper


  Function      Wrapper      Security
Specification   Generator    Wrapper

                 Flags
                            Robustness
                            Wrapper




                                …
            Micro-Generators




Generator
                Wrapper Types
 Data Collection Wrappers:
  – collect failure data and usage data
 Security Wrapper: [SRDS2001]
  – detect buffer overflows on stack and heap
 Robustness Wrappers: [DSN2002]
  – prevent segmentation failures
  – try to keep applications running
 Retry Wrapper: [ISSRE 2002]
  – retry failed function calls
…
                Wrapper Types
 Data Collection Wrappers:
  – collect failure data and usage data
 Security Wrapper: [SRDS2001]
  – detect buffer overflows on stack and heap
 Robustness Wrappers: [DSN2002]
  – prevent segmentation failures
  – try to keep applications running
 Retry Wrapper: [ISSRE 2002]
  – retry failed function calls
…
   Creating Profiling Wrappers
• Create Profile Wrapper:
  > profile_app ls
• Run wrapped ls:
  > wrapped_ls/ls
• Output of profile wrapper in XML
Profiling Wrapper
                Wrapper Types
 Data Collection Wrappers:
  – collect failure data and usage data
 Security Wrapper: [SRDS2001]
  – detect buffer overflows on stack and heap
 Robustness Wrappers: [DSN2002]
  – prevent segmentation failures
  – try to keep applications running
 Retry Wrapper: [ISSRE 2002]
  – retry failed function calls
…
            Security Wrapper
• Currently the wrapper can detect
  – heap smashing attacks (caused by C-library func.)
  – stack smashing attacks
• Stack Smashing Detection:
  – based on an approach by LibSafe
  – uses gcc frame pointers to check that return
    address is not overwritten
    Creating Security Wrappers
• Create Wrapper for individual library:
  > protect_library /lib/libc.so
• Create Wrapper for all libraries:
  > protect_all_libraries
• Info about Security Wrappers in XML
                Wrapper Types
 Data Collection Wrappers:
  – collect failure data and usage data
 Security Wrapper: [SRDS2001]
  – detect buffer overflows on stack and heap
 Robustness Wrappers: [DSN2002]
  – prevent segmentation failures
  – try to keep applications running
 Retry Wrapper: [ISSRE 2002]
  – retry failed function calls
…
Robustness Wrapper tested with Ballista
   Performance Measurements
• Pentium 3, 864Mhz, 384 Mbytes RAM
• Linux 2.4.4 kernel, SuSE 7.2
• Performance data:
  – each data point is 10% trimmed mean of 100
    executions
Performance
                    Related Work
• Formal analysis
   – Can verify deep property of the system.
   – Usually abstract away many implementation details.
• Static analysis
   – Can check all the control paths in the program
   – Requires source code access.
• Ballista
   – Use fault-injection experiments to evaluate the robustness of
     libraries and operating systems.
• Xept
   – Language/compiler to generate wrappers
               Limitations
• Cannot prove correctness of the program.
• Only works for applications that are
  dynamically linked.
• Only detect faults related to library
  functions.
• The quality of fault-injection experiments
  depends on the coverage of the test cases.
       Conclusion/Future Work
• Automation achieves scalability.
• Flexible architecture pays off in the long run
   – Facilitates code reuse.
   – Easy debugging, optimization.
• Future work
   – Collect statistics on failure causes of common
     applications.
   – Generate better test hypothesis for fault-injection
     experiments.

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:1
posted:3/7/2013
language:English
pages:53