Error Propagation Analysis for File Systems Cindy Rubio-Gonzlez, - - PowerPoint PPT Presentation

error propagation analysis for file systems
SMART_READER_LITE
LIVE PREVIEW

Error Propagation Analysis for File Systems Cindy Rubio-Gonzlez, - - PowerPoint PPT Presentation

Error Propagation Analysis for File Systems Cindy Rubio-Gonzlez, Haryadi S. Gunawi, Ben Liblit, Remzi H. Arpaci-Dusseau, and Andrea C. Arpaci-Dusseau University of Wisconsin-Madison PLDI09 ECS 289C Seminar on Program


slide-1
SLIDE 1

Error Propagation Analysis for File Systems

Cindy Rubio-González, Haryadi S. Gunawi, Ben Liblit, Remzi H. Arpaci-Dusseau, and Andrea C. Arpaci-Dusseau

¡

ECS 289C Seminar on Program Analysis

February 17th, 2015

¡

University of Wisconsin-Madison ¡ PLDI’09 ¡

slide-2
SLIDE 2

2

Motivation

  • Incorrect error handling

Incorrect error handling → serious consequences

  • Silent data corruption, data loss, system crashes, etc.
  • Particular focus on file systems
  • Store massive amounts of data
  • Used everywhere!

§ Home use: photos, movies, tax returns § Servers: network file servers, search engines

  • Systems software plays an important role
  • Designed to operate the computer hardware
  • Provides platform for running application software
  • Broken systems software → Broken user applications!
slide-3
SLIDE 3

3

Error Handling

Error Propagation + Error Recovery

ERROR ¡

HARDWARE ¡

ERROR ¡

USER-­‑LEVEL ¡ APPLICATION ¡ SYSTEMS ¡SOFTWARE ¡

ERROR ¡ ERROR ¡

Error Recovery:

  • Logging
  • Notifying
  • Re-trying

Incorrect error handling Incorrect error handling → longstanding problem

Run-time Errors

HARDWARE ¡

slide-4
SLIDE 4

4

Return-Code Idiom

  • Run-time errors represented as integer values
  • Widely used in systems software written in C
  • Also used in large C++ applications
  • Propagated through variable assignments and

function return values

slide-5
SLIDE 5

5

Error Codes in Linux

slide-6
SLIDE 6

Example of Error-Propagation Bug

Silent ¡data ¡ loss!

Incorrect error propagation in IBM JFS Linux file system

read-only file-system error diWrite ¡may return EIO ¡error rc ¡not acknowledged by error reporting/recovery code error stored in rc ¡is lost! function returns variable ¡rc ¡ 1 ¡int ¡txCommit(...) ¡{ ¡ 2 ¡ ¡ ¡... ¡ 3 ¡ ¡ ¡if ¡(isReadOnly(...)) ¡{ ¡ 4 ¡ ¡ ¡ ¡ ¡rc ¡= ¡-­‑EROFS; ¡ 5 ¡ ¡ ¡ ¡ ¡... ¡ 6 ¡ ¡ ¡ ¡ ¡goto ¡TheEnd; ¡ 7 ¡ ¡ ¡} ¡... ¡ 8 ¡ ¡ ¡if ¡(rc ¡= ¡diWrite(...)) ¡ 9 ¡ ¡ ¡ ¡ ¡txAbort(...); ¡ 10 ¡ ¡TheEnd: ¡return ¡rc; ¡ 11 ¡} ¡ ¡ 13 ¡int ¡diFree(...) ¡{ ¡ 14 ¡ ¡ ¡... ¡ 15 ¡ ¡ ¡rc ¡= ¡txCommit(...); ¡ 16 ¡ ¡ ¡... ¡ 17 ¡ ¡ ¡return ¡0; ¡ 18 ¡}

6

slide-7
SLIDE 7

7

Source ¡code ¡ Bug ¡Reports ¡ Static Program Analysis Set of error codes each variable may contain at each program point Second pass over code to find: 1) Overwritten errors 2) Out-of-scope errors 3) Unsaved errors Sample path for each bug found Source code + Error code definitions Error ¡PropagaEon ¡ Analysis ¡ Find ¡Error-­‑PropagaEon ¡ Bugs ¡

High-Level Approach

slide-8
SLIDE 8
  • Finds set of error codes each variable may

contain at each program point

  • Interprocedural, flow- and context-sensitive static

program analysis

Error Propagation Analysis

  • Formulated and solved using weighted

pushdown systems (WPDS)

8

slide-9
SLIDE 9

Weighted Pushdown Systems

  • Control flow is encoded using Pushdown System (PDS)
  • Data flow encoded as transfer functions (or weights)
  • n PDS rules
  • Elements of a set S that constitutes a bounded idempotent

semiring

  • Computes “meet-over-all-paths” solution

9

S = (D, ⊕, ⊗, ¯ 0, ¯ 1)

slide-10
SLIDE 10

Example of a mapping

¡

Mappings Describing Transfer Functions

V: set of variables C: set of error-code constants

¡

Definition

¡

Ident[x ↦ {EROFS}]

OK ¡ EROFS ¡ EIO ¡ x ¡ y ¡ OK ¡ EROFS ¡ EIO ¡ x ¡ y ¡

D = {w|w : V ∪ C → 2V ∪C}

Example

1 ¡ ¡if ¡(...) ¡{ ¡ 2 ¡ ¡ ¡ ¡x ¡= ¡EROFS; ¡ 3 ¡ ¡} ¡ 4 ¡ ¡else ¡{ ¡ 5 ¡ ¡ ¡ ¡x ¡= ¡EIO; ¡ 6 ¡ ¡} ¡ 7 ¡ ¡y ¡= ¡x; ¡

w

D = {w|w : V ∪ C → 2V ∪C}

10

slide-11
SLIDE 11

Combining Mappings:

Modeling merging of control flow paths and ¡ where ¡ Definition of combine operator

¡

Ident[x ↦ {EROFS}] Ident[x ↦ {EIO}] Ident[x ↦ {EROFS, EIO}]

Example

where

¡

and

¡

EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡ EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡ EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡ EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡ EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡ EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡

1 ¡ ¡if ¡(...) ¡{ ¡ 2 ¡ ¡ ¡ ¡x ¡= ¡EROFS; ¡ 3 ¡ ¡} ¡ 4 ¡ ¡else ¡{ ¡ 5 ¡ ¡ ¡ ¡x ¡= ¡EIO; ¡ 6 ¡ ¡} ¡ 7 ¡ ¡y ¡= ¡x; ¡

MERGING BRANCHES 11

w1, w2 ∈ D

e ∈ V ∪ C

(w1 ⊕ w2)(e) ≡ w1(e) ∪ w2(e)

w1

w2

w1 ⊕ w2

slide-12
SLIDE 12

EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡ EROFS ¡ OK ¡ EIO ¡ x ¡ y ¡

Extending Mappings:

Modeling sequential control flow

Definition of extend operator

¡

Ident[x ↦ {EIO, EROFS}] Ident[y ↦ {x}] Ident[x ↦ {EIO, EROFS}, y ↦ {EIO, EROFS}]

where ¡

w1, w2 ∈ D e ∈ V ∪ C

(w1 ⊗ w2)(e) ≡ [

e02w2(e)

w1(e0)

Example

OK ¡ OK ¡ EROFS ¡ EIO ¡ x ¡ y ¡ EROFS ¡ EIO ¡ x ¡ y ¡

w1 w2

1 ¡ ¡if ¡(...) ¡{ ¡ 2 ¡ ¡ ¡ ¡x ¡= ¡EROFS; ¡ 3 ¡ ¡} ¡ 4 ¡ ¡else ¡{ ¡ 5 ¡ ¡ ¡ ¡x ¡= ¡EIO; ¡ 6 ¡ ¡} ¡ 7 ¡ ¡y ¡= ¡x; ¡

EXTENDING 12

where

¡

and

¡ (w1 ⊗ w2)(e) ≡ [

e02w2(e)

w1(e0)

w1, w2 ∈ D

e ∈ V ∪ C

w1

w2

w1 ⊗ w2

slide-13
SLIDE 13

Detecting Handled Errors

  • Handled errors vs. unhandled errors
  • Adopt simple definition of “correct handling”
  • Ident[y ↦ {OK}]

OK ¡ EIO ¡ OK ¡ EROFS ¡ EIO ¡ x ¡ y ¡ EROFS ¡ x ¡ y ¡

Example

logging error 1 ¡ ¡if ¡(...) ¡{ ¡ 2 ¡ ¡ ¡ ¡x ¡= ¡EROFS; ¡ 3 ¡ ¡} ¡ 4 ¡ ¡else ¡{ ¡ 5 ¡ ¡ ¡ ¡x ¡= ¡EIO; ¡ 6 ¡ ¡} ¡ 7 ¡ ¡y ¡= ¡x; ¡ 8 ¡ ¡printk(“error ¡%d\n”, ¡y); ¡

13

  • Error-handling functions file-system specific
  • ext3_error, jfs_error, etc.

¡

slide-14
SLIDE 14

14

  • Mappings representing execution from the

beginning of the program to any program point

  • Meet over all paths value
  • Errors each variable may contain at each program point

¡

  • For each mapping a subset of inspected paths

whose combine is equal to

  • Explains why value is as claimed

Analysis Result

slide-15
SLIDE 15

Dropped Errors

OVERWRITTEN OUT OF SCOPE UNSAVED

Error overwritten with new value Variable storing error goes out of scope Error returned by a function is not saved by the caller

15

Error-code instances that vanish before being handled ¡

slide-16
SLIDE 16

Program Transformations

EIO ¡is not saved EIO is returned

  • 1. Transform unsaved errors into out-of-scope errors

¡

OUT OF SCOPE UNSAVED

1 ¡int ¡bar(...) ¡{ ¡ 2 ¡ ¡return ¡–EIO; ¡ 3 ¡} ¡ ¡ ¡ 5 ¡int ¡foo(...) ¡{ ¡ 6 ¡ ¡ 7 ¡ ¡... ¡ 8 ¡ ¡bar(); ¡ ¡ ¡ 9 ¡ ¡... ¡ 10 ¡ ¡ 11 ¡ 12 ¡return ¡...; ¡ 13} ¡ ¡

16

slide-17
SLIDE 17

tmp ¡is out of scope EIO ¡is saved in

temporary variable

Program Transformations

  • 1. Transform unsaved errors into out-of-scope errors

¡

OUT OF SCOPE UNSAVED

1 ¡int ¡bar(...) ¡{ ¡ 2 ¡ ¡return ¡–EIO; ¡ 3 ¡} ¡ ¡ ¡ ¡ 5 ¡int ¡foo(...) ¡{ ¡ 6 ¡ ¡ 7 ¡ ¡... ¡ 8 ¡ ¡int ¡tmp ¡= ¡bar(); ¡ ¡ ¡ 9 ¡ ¡... ¡ 10 ¡ ¡ 11 ¡ 12 ¡return ¡...; ¡ 13} ¡ ¡

17

slide-18
SLIDE 18

1 ¡int ¡bar(...) ¡{ ¡ 2 ¡ ¡return ¡–EIO; ¡ 3 ¡} ¡ ¡ ¡ ¡ 5 ¡int ¡foo(...) ¡{ ¡ 6 ¡ ¡ 7 ¡ ¡... ¡ 8 ¡ ¡int ¡tmp ¡= ¡bar(); ¡ ¡ ¡ 9 ¡ ¡... ¡ 10 ¡ ¡ 11 ¡tmp ¡= ¡OK; ¡ 12 ¡return ¡...; ¡ 13} ¡ ¡ 1 ¡int ¡bar(...) ¡{ ¡ 2 ¡ ¡return ¡–EIO; ¡ 3 ¡} ¡ ¡ ¡ ¡ 5 ¡int ¡foo(...) ¡{ ¡ 6 ¡ ¡ 7 ¡ ¡... ¡ 8 ¡ ¡int ¡tmp ¡= ¡bar(); ¡ ¡ ¡ 9 ¡ ¡... ¡ 10 ¡ ¡ 11 ¡ 12 ¡return ¡...; ¡ 13} ¡ ¡

Assigning ¡OK ¡at the end

  • f the function

EIO ¡is overwritten

Program Transformations

  • 2. Transform out-of-scope errors into overwritten errors

¡

OUT OF SCOPE UNSAVED OVERWRITTEN

tmp ¡is out of scope

18

slide-19
SLIDE 19

Finding Dropped Errors

  • 2. Apply error-propagation analysis
  • 3. Find whether each assignment may overwrite an error
  • Before each assignment t ¡= ¡s, retrieve the associated mapping
  • Let ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡, , ¡and ¡ ¡ ¡ ¡ ¡ ¡be the set of all error codes

(1) ¡If No error overwrite (2) If OK to overwrite same error ¡ (3) Otherwise ¡ ¡ ¡ ¡ Error overwrite!

  • 1. Transform all error-propagation bugs into overwrites
  • 19

w

T = w(t) S = w(s)

E

T ∩ E = {} T ∩ E = S = {e}

slide-20
SLIDE 20

20

1 ¡ ¡int ¡nextId(){ ¡ 2 ¡ ¡ ¡ ¡static ¡int ¡id; ¡ 3 ¡ ¡ ¡ ¡return ¡id++; ¡ 4 ¡ ¡} ¡ 5 ¡ 6 ¡ ¡int ¡getError(){ ¡ 7 ¡ ¡ ¡ ¡return ¡–EIO; ¡ 8 ¡ ¡} ¡ 9 ¡ 10 ¡int ¡load(){ ¡ 11 ¡ ¡ ¡int ¡status, ¡result ¡= ¡0; ¡ 12 ¡ 13 ¡ ¡ ¡if ¡(nextId()) ¡ 14 ¡ ¡ ¡ ¡ ¡ ¡status ¡= ¡getError(); ¡ 15 ¡ ¡ 16 ¡ ¡ ¡result ¡= ¡status; ¡ 17 ¡ 18 ¡ ¡ ¡if ¡(nextId()) ¡ 19 ¡ ¡ ¡ ¡ ¡ ¡result ¡= ¡-­‑EPIPE; ¡ ¡ 20 ¡ 21 ¡ ¡return ¡result; ¡ 22 ¡} ¡ ¡

  • verwriting unchecked error in “result”

unchecked error “EIO” is returned “status” receives unchecked error from function “getError” “result” receives unchecked error from “status” “result” has unchecked error “result” has unchecked error

Sample Output

slide-21
SLIDE 21

example.c:16: ¡“result” ¡receives ¡unchecked ¡error ¡from ¡“status” ¡

21

1 ¡ ¡int ¡nextId(){ ¡ 2 ¡ ¡ ¡ ¡static ¡int ¡id; ¡ 3 ¡ ¡ ¡ ¡return ¡id++; ¡ 4 ¡ ¡} ¡ 5 ¡ 6 ¡ ¡int ¡getError(){ ¡ 7 ¡ ¡ ¡ ¡return ¡–EIO; ¡ 8 ¡ ¡} ¡ 9 ¡ 10 ¡int ¡load(){ ¡ 11 ¡ ¡ ¡int ¡status, ¡result ¡= ¡0; ¡ 12 ¡ 13 ¡ ¡ ¡if ¡(nextId()) ¡ 14 ¡ ¡ ¡ ¡ ¡ ¡status ¡= ¡getError(); ¡ 15 ¡ ¡ 16 ¡ ¡ ¡result ¡= ¡status; ¡ 17 ¡ 18 ¡ ¡ ¡if ¡(nextId()) ¡ 19 ¡ ¡ ¡ ¡ ¡ ¡result ¡= ¡-­‑EPIPE; ¡ ¡ 20 ¡ 21 ¡ ¡return ¡result; ¡ 22 ¡} ¡ ¡

Complete diagnostic path trace

example.c:14: ¡“status” ¡receives ¡unchecked ¡error ¡from ¡funcEon ¡“getError” ¡ example.c:18: ¡“result” ¡has ¡unchecked ¡error ¡ example.c:3: ¡“result” ¡has ¡unchecked ¡error ¡ example.c:18: ¡“result” ¡has ¡unchecked ¡error ¡ example.c:19: ¡overwriEng ¡unchecked ¡error ¡in ¡“result” ¡ example.c:7: ¡unchecked ¡error ¡“EIO” ¡is ¡returned ¡

Diagnostic path slice

example.c:14: ¡“status” ¡receives ¡unchecked ¡error ¡from ¡funcEon ¡“getError” ¡ example.c:16: ¡“result” ¡receives ¡unchecked ¡error ¡from ¡“status” ¡ example.c:19: ¡overwriEng ¡unchecked ¡error ¡in ¡“result” ¡ example.c:7: ¡unchecked ¡error ¡“EIO” ¡is ¡returned ¡

Sample Output

slide-22
SLIDE 22

25 ¡ ¡8% ¡ 18 ¡ 6% ¡ 269 ¡ 86% ¡

True ¡Bugs ¡Per ¡Category ¡

Overwri\en ¡ Out ¡of ¡Scope ¡ Unsaved ¡

44 ¡ 23% ¡ 48 ¡ 26% ¡ 97 ¡ 51% ¡

False ¡Posi2ves ¡Per ¡Category ¡

Overwri\en ¡ Out ¡of ¡Scope ¡ Unsaved ¡

22

  • Case studies: CIFS, ext3, ext4, IBM JFS,

ReiserFS and VFS in Linux 2.6.27 kernel

¡

  • 501 bug reports in total

¡

312 ¡reports ¡ 189 ¡reports ¡

Many ¡errors ¡ actually ¡dropped! ¡

Experimental Results

slide-23
SLIDE 23

23

  • 269 true bugs, 97 false positives

¡

  • Most common unsaved errors: EIO, ENOSPC and

ENOMEM

¡

68 ¡ 69 ¡ 58 ¡ 38 ¡ 24 ¡ 12 ¡

Unsaved ¡True ¡Bugs ¡per ¡File ¡System ¡

ext4 ¡ ext3 ¡ IBM ¡JFS ¡ VFS ¡ ReiserFS ¡ cifs ¡

Unsaved Errors

slide-24
SLIDE 24

24

  • Inconsistent use of function return values
  • For example, a function whose return value is:
  • Saved at 17 call sites
  • Unsaved at 35 other call sites

§ 9 out of 35 identified as true bugs § The rest are false positives (errors are intentionally dropped!)

  • Some developers have suggested to use annotations

to mark intentionally dropped errors

Inconsistencies

slide-25
SLIDE 25

1 ¡ ¡buffer_head ¡*b ¡= ¡NULL; ¡ 2 ¡ ¡... ¡ 3 ¡ ¡if ¡(buffer_dirty(b)) ¡ ¡ 4 ¡ ¡ ¡ ¡ ¡sync_dirty_buffer(b); ¡ 5 ¡ ¡ ¡ 6 ¡ ¡if ¡(!buffer_uptodate(b)) ¡{ ¡ ¡ 7 ¡ ¡ ¡ ¡ ¡reiserfs_warning(...); ¡ 8 ¡ ¡ ¡ ¡ ¡retval ¡= ¡-­‑EIO; ¡ 9 ¡ ¡} ¡ ¡

25

  • Redundant error reporting

¡

  • Error paths: already failing

¡

  • Met preconditions: cannot possibly fail

¡

An error may not be saved Checking “b”

False Positives – Unsaved Errors

15% ¡

¡

85% ¡

¡

slide-26
SLIDE 26

(Updated) Running Time

91 ¡ 83 ¡ 97 ¡ 93 ¡ 88 ¡

  • 3.2 GHz Intel Pentium 4 processor workstation with 3 GB RAM

¡

0 ¡ 0.5 ¡ 1 ¡ 1.5 ¡ 2 ¡ 2.5 ¡ CIFS ¡ ext3 ¡ ext4 ¡ IBM ¡JFS ¡ ReiserFS ¡ Running ¡Time ¡(in ¡minutes) ¡ KLOC: ¡

26

slide-27
SLIDE 27

0 ¡ 100 ¡ 200 ¡ 300 ¡ 400 ¡ CIFS ¡ ext3 ¡ ext4 ¡ IBM ¡JFS ¡ ReiserFS ¡ Memory ¡Usage ¡(in ¡MB) ¡

(Updated) Memory Usage

91 ¡ 83 ¡ 97 ¡ 93 ¡ 88 ¡

  • 3.2 GHz Intel Pentium 4 processor workstation with 3 GB RAM

¡

KLOC: ¡

27

slide-28
SLIDE 28

28

  • 43 other Linux file systems
  • Bug reports to be examined

¡

  • Different Linux versions
  • Significant evolution in each release

¡

  • NASA/JPL Laboratory for Reliable Software
  • Using tool to check code in the Mars Science Laboratory
  • Found one real error propagation bug so far ¡

¡

“We’ve found a legitimate problem…We call a non-void function (that can return some critical error codes) and don’t assign the return value, dropping some nice things such as EASSERT, EABOUND, and EEBADHDR on the ground. We would have expected the compiler or [another code-checking tool] to catch that, actually…We’re going to rerun on a big update to the code soon.”

Other File Systems

slide-29
SLIDE 29

29

  • Eliminating error propagation bugs increases the

trustworthiness of file systems and, in turn, of computer systems as a whole

  • Proposed interprocedural flow- and context-sensitive

static analysis that detects overwritten, out-of-scope and unsaved unchecked errors

  • Analyzed five Linux file systems and the VFS
  • Reported 501 bug reports, of which 312 are true bugs

Summary

slide-30
SLIDE 30

30

Developers Feedback

“I think this is an excellent way of detecting bugs that happen rarely enough that there are no good reproduction cases, but likely hit users on occasion and are

  • therwise impossible to diagnose.” - Andreas Dilger (ext4)

¡

“Ew, this [bug] is hard to figure out.” - Matthew Wilcox (FS)

¡

“Thank you for helping to improve JFS!” - David Kleikamp (IBM JFS) “So that is a nice find.” - Jan Harkes (Coda)

¡

“Thank you for looking into this. It’s a great idea.” - Matthew Wilcox (FS)

¡

“Thanks for your efforts!” ¡-­‑ ¡Jeff Mahoney (ReiserFS)

¡

“This sounds interesting - please forward them to me.” ¡-­‑ ¡Steve French(CIFS)

¡ ¡ ¡