Error Propagation Analysis for File Systems � Cindy Rubio-González, Haryadi S. Gunawi, Ben Liblit, Remzi H. Arpaci-Dusseau, and Andrea C. Arpaci-Dusseau � ¡ University of Wisconsin-Madison ¡ PLDI’09 ¡ ECS 289C Seminar on Program Analysis February 17th, 2015 ¡
� Motivation � • Systems software plays an important role � o Designed to operate the computer hardware � o Provides platform for running application software � • Particular focus on file systems � o Store massive amounts of data � o Used everywhere! � § Home use: photos, movies, tax returns � § Servers: network file servers, search engines � • Incorrect error handling Incorrect error handling → serious consequences � o Silent data corruption, data loss, system crashes, etc. � • Broken systems software → Broken user applications! � 2
Error Handling � Error Propagation + Error Recovery � USER-‑LEVEL ¡ APPLICATION ¡ SYSTEMS ¡SOFTWARE ¡ ERROR ¡ Error Recovery: � ERROR ¡ • Logging � • Notifying � • Re-trying � Run-time ERROR ¡ ERROR ¡ Errors � HARDWARE ¡ HARDWARE ¡ Incorrect error handling → longstanding problem � Incorrect error handling 3
Return-Code Idiom � • Widely used in systems software written in C � • Also used in large C++ applications � • Run-time errors represented as integer values � • Propagated through variable assignments and function return values � 4
Error Codes in Linux � 5
Example of Error-Propagation Bug � 1 ¡ int ¡txCommit(...) ¡{ ¡ 2 ¡ ¡ ¡... ¡ 3 ¡ ¡ ¡ if ¡(isReadOnly(...)) ¡{ ¡ 4 ¡ ¡ ¡ ¡ ¡rc ¡= ¡-‑EROFS; ¡ read-only file-system error � 5 ¡ ¡ ¡ ¡ ¡... ¡ 6 ¡ ¡ ¡ ¡ ¡ goto ¡TheEnd; ¡ 7 ¡ ¡ ¡} ¡... ¡ 8 ¡ ¡ ¡ if ¡(rc ¡= ¡diWrite(...)) ¡ diWrite ¡ may return EIO ¡ error � 9 ¡ ¡ ¡ ¡ ¡txAbort(...); ¡ function returns variable ¡ rc ¡ 10 ¡ ¡TheEnd: ¡ return ¡rc; ¡ 11 ¡} ¡ ¡ 13 ¡ int ¡diFree(...) ¡{ ¡ 14 ¡ ¡ ¡... ¡ 15 ¡ ¡ ¡rc ¡= ¡txCommit(...); ¡ rc ¡ not acknowledged by error 16 ¡ ¡ ¡... ¡ reporting/recovery code � 17 ¡ ¡ ¡ return ¡0; ¡ Silent ¡data ¡ 18 ¡} error stored in rc ¡ is lost! � loss ! Incorrect error propagation in IBM JFS Linux file system � 6
High-Level Approach � Source ¡code ¡ Source code + Error code definitions � Static Program Analysis � Error ¡PropagaEon ¡ Analysis ¡ Set of error codes each variable may contain at each program point � Second pass over code to find: � Find ¡Error-‑PropagaEon ¡ 1) Overwritten errors � Bugs ¡ 2) Out-of-scope errors � 3) Unsaved errors � Bug ¡Reports ¡ Sample path for each bug found � 7
Error Propagation Analysis � • Interprocedural, flow- and context-sensitive static program analysis � • Finds set of error codes each variable may contain at each program point � • Formulated and solved using weighted pushdown systems (WPDS) � 8
Weighted Pushdown Systems � • Control flow is encoded using Pushdown System (PDS) � • Data flow encoded as transfer functions (or weights) on PDS rules � o Elements of a set S that constitutes a bounded idempotent semiring � S = ( D, ⊕ , ⊗ , ¯ 0 , ¯ 1) • Computes “meet-over-all-paths” solution � 9
Mappings Describing Transfer Functions � Definition � Example � D = { w | w : V ∪ C → 2 V ∪ C } ¡ D = { w | w : V ∪ C → 2 V ∪ C } 1 ¡ ¡if ¡(...) ¡{ ¡ 2 ¡ ¡ ¡ ¡ x ¡= ¡ EROFS; ¡ V: set of variables � 3 ¡ ¡} ¡ C: set of error-code constants � 4 ¡ ¡ else ¡{ ¡ ¡ 5 ¡ ¡ ¡ ¡ x ¡= ¡ EIO; ¡ 6 ¡ ¡} ¡ 7 ¡ ¡y ¡= ¡x; ¡ Example of a mapping � w ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ Ident [x ↦ {EROFS}] � 10
Combining Mappings: � ⊕ Modeling merging of control flow paths � Definition of combine operator � Example � ¡ 1 ¡ ¡if ¡(...) ¡{ ¡ ( w 1 ⊕ w 2 )( e ) ≡ w 1 ( e ) ∪ w 2 ( e ) 2 ¡ ¡ ¡ ¡ x ¡= ¡ EROFS; ¡ 3 ¡ ¡} ¡ MERGING w 1 , w 2 ∈ D e ∈ V ∪ C where � and � BRANCHES � where ¡ and ¡ 4 ¡ ¡ else ¡{ ¡ ¡ ¡ 5 ¡ ¡ ¡ ¡ x ¡= ¡ EIO; ¡ 6 ¡ ¡} ¡ 7 ¡ ¡y ¡= ¡x; ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ w 1 w 2 w 1 ⊕ w 2 Ident [x ↦ {EROFS}] � Ident [x ↦ {EIO}] � Ident [x ↦ {EROFS, EIO}] � 11
Extending Mappings: � ⊗ Modeling sequential control flow � Definition of extend operator � Example � ¡ [ [ w 1 ( e 0 ) 1 ¡ ¡if ¡(...) ¡{ ¡ ( w 1 ⊗ w 2 )( e ) ≡ w 1 ( e 0 ) ( w 1 ⊗ w 2 )( e ) ≡ 2 ¡ ¡ ¡ ¡ x ¡= ¡ EROFS; ¡ e 0 2 w 2 ( e ) 3 ¡ ¡} ¡ e 0 2 w 2 ( e ) where ¡ 4 ¡ ¡ else ¡{ ¡ EXTENDING � w 1 , w 2 ∈ D e ∈ V ∪ C where � and � w 1 , w 2 ∈ D e ∈ V ∪ C 5 ¡ ¡ ¡ ¡ x ¡= ¡ EIO; ¡ ¡ ¡ 6 ¡ ¡} ¡ 7 ¡ ¡y ¡= ¡x; ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ w 1 Ident [x ↦ {EIO, EROFS}] � w 1 Ident [y ↦ {x}] � w 2 w 2 x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ w 1 ⊗ w 2 x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ Ident [x ↦ {EIO, EROFS}, y ↦ {EIO, EROFS}] � 12
� Detecting Handled Errors � • Handled errors vs. unhandled errors � � • Adopt simple definition of “correct handling” � Example � 1 ¡ ¡if ¡(...) ¡{ ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ 2 ¡ ¡ ¡ ¡ x ¡= ¡ EROFS; ¡ 3 ¡ ¡} ¡ 4 ¡ ¡ else ¡{ ¡ 5 ¡ ¡ ¡ ¡ x ¡= ¡ EIO; ¡ 6 ¡ ¡} ¡ x ¡ y ¡ EIO ¡ EROFS ¡ OK ¡ 7 ¡ ¡y ¡= ¡x; ¡ Ident [y ↦ {OK}] � 8 ¡ ¡printk(“error ¡%d\n”, ¡y); ¡ logging error � • Error-handling functions file-system specific � o ext3_error, jfs_error, etc. � ¡ 13
Analysis Result � • Mappings representing execution from the beginning of the program to any program point � o Meet over all paths value � o Errors each variable may contain at each program point � ¡ • For each mapping a subset of inspected paths whose combine is equal to � o Explains why value is as claimed � 14
Dropped Errors � Error-code instances that vanish before being handled ¡ OVERWRITTEN � Error overwritten with new value � OUT OF SCOPE � Variable storing error goes out of scope � UNSAVED � Error returned by a function is not saved by the caller � 15
Program Transformations � 1. Transform unsaved errors into out-of-scope errors � ¡ 1 ¡ int ¡ bar(...) ¡{ ¡ 2 ¡ ¡ return ¡–EIO; ¡ EIO is returned � 3 ¡} ¡ ¡ ¡ 5 ¡ int ¡foo(...) ¡{ ¡ 6 ¡ ¡ 7 ¡ ¡... ¡ OUT OF SCOPE � 8 ¡ ¡bar(); ¡ ¡ ¡ EIO ¡ is not saved � 9 ¡ ¡... ¡ 10 ¡ ¡ 11 ¡ 12 ¡ return ¡...; ¡ UNSAVED � 13} ¡ ¡ 16
Program Transformations � 1. Transform unsaved errors into out-of-scope errors � ¡ 1 ¡ int ¡ bar(...) ¡{ ¡ 2 ¡ ¡ return ¡–EIO; ¡ 3 ¡} ¡ ¡ ¡ ¡ 5 ¡ int ¡foo(...) ¡{ ¡ 6 ¡ ¡ 7 ¡ ¡... ¡ OUT OF SCOPE � 8 ¡ ¡ int ¡tmp ¡= ¡bar(); ¡ ¡ ¡ EIO ¡ is saved in 9 ¡ ¡... ¡ temporary variable � 10 ¡ ¡ 11 ¡ 12 ¡ return ¡...; ¡ tmp ¡ is out of scope � UNSAVED � 13} ¡ ¡ 17
Program Transformations � 2. Transform out-of-scope errors into overwritten errors � ¡ 1 ¡ int ¡ bar(...) ¡{ ¡ 1 ¡ int ¡ bar(...) ¡{ ¡ OVERWRITTEN � 2 ¡ ¡ return ¡–EIO; ¡ 2 ¡ ¡ return ¡–EIO; ¡ 3 ¡} ¡ 3 ¡} ¡ ¡ ¡ ¡ ¡ ¡ ¡ 5 ¡ int ¡foo(...) ¡{ ¡ 5 ¡ int ¡foo(...) ¡{ ¡ 6 ¡ ¡ 6 ¡ ¡ 7 ¡ ¡... ¡ 7 ¡ ¡... ¡ OUT OF SCOPE � 8 ¡ ¡ int ¡tmp ¡= ¡bar(); ¡ ¡ ¡ 8 ¡ ¡ int ¡tmp ¡= ¡bar(); ¡ ¡ ¡ 9 ¡ ¡... ¡ 9 ¡ ¡... ¡ 10 ¡ ¡ 10 ¡ ¡ 11 ¡tmp ¡= ¡OK; ¡ 11 ¡ Assigning ¡ OK ¡ at the end EIO ¡ is overwritten � 12 ¡ return ¡...; ¡ 12 ¡ return ¡...; ¡ tmp ¡ is out of scope � of the function � UNSAVED � 13} ¡ ¡ 13} ¡ ¡ 18
� � � Finding Dropped Errors � 1. Transform all error-propagation bugs into overwrites � 2. Apply error-propagation analysis � 3. Find whether each assignment may overwrite an error � • Before each assignment t ¡= ¡s , retrieve the associated mapping � w Let ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ , , ¡ and ¡ ¡ ¡ ¡ ¡ ¡ be the set of all error codes � • T = w ( t ) S = w ( s ) E (1) ¡ If No error overwrite � T ∩ E = {} (2) If OK to overwrite same error ¡ T ∩ E = S = { e } (3) Otherwise ¡ ¡ ¡ ¡ Error overwrite! � 19
Recommend
More recommend