by D' Engler, B' Chelf, A' Chou, S' Hallem - PowerPoint PPT Presentation

1 / 32
About This Presentation
Title:

by D' Engler, B' Chelf, A' Chou, S' Hallem

Description:

Checking System Rules Using System-Specific, Programmer-Written Compiler Extensions ... {z--} == {err('post-decrement' ... decrements it during unloading (by ... – PowerPoint PPT presentation

Number of Views:124
Avg rating:3.0/5.0
Slides: 33
Provided by: psw9
Category:

less

Transcript and Presenter's Notes

Title: by D' Engler, B' Chelf, A' Chou, S' Hallem


1
Checking System Rules Using System-Specific,
Programmer-Written Compiler Extensions
  • by D. Engler, B. Chelf, A. Chou, S. Hallem
  • published in OSDI 2000
  • Hong,Shin

2
Contents
  • Introduction
  • Meta-level Compilation
  • Checking Assertion Side-effect
  • Temporal Ordering
  • Enforcing Rules Globally
  • Linux Mutual Exclusion
  • Conclusion

3
Introduction 1/4
  • System software must obey many rules.
  • e.g. check user permission before modifying
    kernel data structures
  • A code that does not obey these rules may crash
    the system.
  • There are several methods to find violations of
    system rules.
  • Model checking
  • Testing
  • Manual inspection

2009-11-16
Checking System Rules Using System-Specific,
Programmer-Written Compiler Extensions
3
4
Introduction 2/4
  • Model checking
  • Pros rigorous checking
  • Cons models are difficult and costly to
    construct
  • Testing
  • Pros working with an actual code
  • Cons not scalable, finding the cause of a test
    failure can be difficult
  • Manual inspection
  • Pros easy adapt to ad hoc coding conventions and
    system rules.
  • Cons impossible for complex codes, reliability
    of manual inspection is erratic.

5
Introduction 3/4
  • One possible alternative is to use static
    compiler analysis to find rule violations.
  • Models are not needed.
  • Static analysis can examine much more paths than
    testing.
  • Reduces the need to construct numerous test cases
  • ?Compilers can be used to enforce system rules
    because many rules have a straightforward mapping
    to program source.

6
Introduction 4/4
  • Meta-level compilation
  • Extends compilers with lightweight,
    system-specific checkers.
  • System implementers write extensions in a
    high-level state-machine language, metal.
  • Using metal, system implementers can specify
    system rules as code patterns.
  • The written extensions are dynamically linked
    into an extensible compiler, xg.
  • The extended compiler detects any rule violation
    in an input code by matching the code to
    specified patterns.

7
Meta-level Compilation 1/6
  • Many system rules describe legal orderings of
    operations or specific contexts where these
    operations can or cannot occur.
  • A meta-level compiler extension can check these
    rules by searching for the corresponding
    operations and checking that codes obey the given
    ordering or contextual restrictions.
  • Metal
  • Compiler extensions are written in a high-level,
    state-machine language, metal.
  • xg compiler translates each input function into
    its internal representation, the extensions are
    applied down every possible execution path in
    that function.

8
Meta-level Compilation 2/6
  • Rule templates
  • Never/always do X
  • e.g. Never use floating point in kernel.
  • Always do X before/after Y
  • e.g. Always check that user given pointers are
    not null before using
  • in kernel.
  • Never do X before/after Y
  • e.g. Never acquire a lock twice.
  • In situation X, do Y
  • e.g. While interrupts are disabled, do not call
    functions that can sleep.
  • In situation X, do Y rather than Z
  • e.g. If code does not share data with interrupt
    handlers, then use
  • spin locks rather than interrupt disabling.

9
Meta-level Compilation 3/6
  • Ex. a metal state-machine to detect (1) when
    interrupts disabled using cli() are not
    re-enabled using either sti() or restore_flags()
    and (2) duplicate enable/disable calls.

inlcude linux-includes.h sm
check_interrupts decl unsigned flags
pat enable sti()
restore_flags(flags) pat disable
cli() is_enabled disable gt
is_disabled enable gt
err(double enable) is_disabled enable
gt is_enabled disable gt
err(double disable)
end_of_path gt
err(exiting w/intr disabled!)
Variables used in patterns
Patterns
States
10
Meta-level Compilation 4/6
is_ enabled
enable/ double enable
disable
enable
is_ disabled
error
disable/ double disable
end of path/ invalid exit
11
Meta-level Compilation 5/6
12
Meta-level Compilation 6/6
  • Metal can specify whether a rule should be
    applied either down all paths (flow sensitive) or
    linearly through the code (flow insensitive).
  • Caching is used to prune redundant code paths
    where state-machine instances follow code paths
    that reach the same state.
  • The system represents the state of an
    state-machine as a vector holding the value of
    its variables.
  • For each node in the input flow-graph, it records
    the set of states where it has been visited.
  • If an state-machine arrives at a node in the same
    state as a previous instance, the system prunes
    it.

13
Checking Assertion Side-effects 1/2
  • We can find incorrect uses of C assert macros
    using meta level compilation.
  • Assertions should not have non-debugging effects.
  • If an assert condition has important
    side-effects, these will disappear when the
    assertion is removed and the program will behave
    incorrectly.
  • If an assertion expression has any assignment
    operations or function invocations, the assertion
    may have side-effects.
  • We can write a metal checker that inspects
    assertion expressions for side-effects.
  • In Xoks ExOS library OS, the extension found 16
    violations in 199 assertions.

14
Checking Assertion Side-effects 2/2
  • include ltassert.hgt
  • sm Assert flow_insensitive
  • decl any expr, x, y, z
  • decl any_call any_fcall
  • decl any_args args
  • start
  • assert(expr) gt
  • mgk_expr_recurse(expr, in_assert)
  • in_assert
  • any_fcall(args) gt err(func call)
  • x y gt err(assignment)
  • z gt err(post-increment)
  • z-- gt err(post-decrement)

apply the extension linearly over input functions
metal provides a set of generic types for
matching different classes of types
a metal procedure call to apply the state-machine
to the expression in expr in the in_assert state
15
Temporal Orderings 1/8
  • Many system operations must (or must not) happen
    in sequence.
  • This constraints are well-suited for compiler
    checking since sequences of operations are
    encoded as literal procedure calls in a code.
  • - Checking copyin/copyout
  • - Checking memory management

16
Temporal Ordering 2/8
  • Checking copyin/copyout
  • Most operating system guard against application
    corruption of kernel memory by using special
    routines to check system call input pointers and
    to move data between user and kernel space.
  • A meta-compilation extension can find errors in
    such code by finding paths where an application
    pointer is used before passing through the
    checking routines.

17
Temporal Ordering 3/8
  • At each system call definition, the extension
    uses a special pattern to find every pointer
    parameter, which it binds to a tainted state.
  • The only legal operations on a tainted variable
    are being (1) killed by an assignment or (2)
    passed as an argument to functions expecting
    tainted input (e.g. kprintf).
  • A tailored version of this checker for Xok
    exokernel code found 18 errors from 187 distinct
    user pointers in the exokernel.

18
Temporal Ordering 4/8
  • Checking memory management
  • An extension checks four common rules to check
    memory management
  • (1) Since memory allocation can fail, kernel
    code must check whether the returned pointer is
    not null before using it.
  • (2) Memory cannot be used after it has been
    freed.
  • (3) Paths that allocate memory and then abort
    with an error should typically deallocate this
    memory before returning.
  • (4) The size of allocated memory cannot be less
    than the size of the object the assigned pointer
    holds.

19
Temporal Ordering 5/8
  • We can write metal state-machine to check the
    memory management conditions.
  • Pointers to allocated storage can be in exactly
    one of four states unknown, null, not_null,
    freed, or okay.
  • A variable is bound to the unknown state at every
    allocation site.
  • When an unknown variable is compared to null, the
    extension sets the variables state on the null
    path to null and on the non-null path to
    not_null.
  • Pointers passed to free transition to the freed
    state.
  • The checker only allows dereferences of pointers
    in not_null state.
  • This extension found 132 errors in Linux.

20
Temporal Ordering 6/8
  • sm null_checker
  • decl scalar sz
  • decl const int retv
  • decl any_ptr v1
  • state decl any_ptr v
  • start, v.all
  • ((v(any)malloc(sz))0) gt
  • truev.null,
    falsev.not_null
  • ((v(any)malloc(sz))!0) gt
  • truev.not_null,
    falsev.null
  • v(any)malloc(sz) gt v.unknown

21
Temporal Ordering 7/8
  • v.unknown, v.null, v.not_null
  • (v0) gt truev.null, falsev.not_null
  • (v!0) gt truev.not_null, truev.null
  • v.unknown, v.not_null return retv gt
  • if (mgk_int_cst(retv) lt0) err(Error path
  • leak!)
  • v.null, v.unknown (any )v gt
  • err(Using ptr illegally!)
  • v.unknown, v.null, v.not_null free(v) gt
    v.freed
  • v.freed free(v) gt err(Dup free!)
  • v gt err(Use after-free!)
  • v.all v v1 gt v.ok

22
Temporal Ordering 8/8
23
Enforcing Rules Globally 1/6
  • The extensions described thus far have been
    implemented as local analyses.
  • Many system rules are context dependent and apply
    globally across functions in a given call chain.
  • Following two Linux rules are checked by global
    analysis
  • - Kernel code cannot call blocking functions
    with interrupts disabled or while holding a spin
    lock.
  • - A dynamically loaded kernel module cannot
    call blocking functions until the modules
    reference count has been properly set.

24
Enforcing Rules Globally 2/6
  • Computing blocking routines
  • We build a list of possibly blocking functions in
    three passes.
  • (1) Make a list of blocking functions manually.
  • e.g. kernel memory allocators called without the
    GFP_ATOMIC flag
  • , routines to move data to or from user
    space.
  • (2) The metal extension marks a function as a
    potentially blocking function if the function
    directly calls blocking functions in the list.
  • (3) Make a global call graph for the entire
    kernel and perform a depth first traversal over
    this call graph calculating which routines have
    any path to a potentially blocking function.

25
Enforcing Rules Globally 3/6
  • Checking blocking deadlock
  • A metal extension can check both rules by
    assuming each routine starts in an enabled state
    with interrupts enabled and no locks held.
  • As it traverses each global code path, if it hits
    a statement that disables interrupt, it goes to a
    disabled state.
  • If it hits a potentially blocking function in a
    disabled state, it reports the global code path
    as an error.
  • The extension found real 79 deadlock errors in
    Linux.

26
Enforcing Rules Globally 4/6
Disable interrupt
Block function
27
Enforcing Rules Globally 5/6
  • Checking module reference counts
  • Linux allows kernel subsystems to be dynamically
    loaded and unloaded.
  • A module has its reference count tracking the
    number of kernel subsystems using the module.
  • A module increment s its reference count during
    loading (by MOD_INC_USE_COUNT)
  • decrements it during unloading (by
    MOD_DEC_USE_COUNT).
  • A module must protect against being unloaded
    while sleeping by incrementing its reference
    count before calling a blocking function.
  • An extension can check for load race condition by
    tracking if a potentially blocking function has
    been called and flagging subsequent
    MOD_INC_USE_COUNT.

28
Enforcing Rules Globally 6/6
Block function
client must be deallocated!
29
Linux Mutual Exclusion 1/2
  • The checks for Linux locking conventions are
    important to avoid deadlock in kernel.
  • Each kernel function must satisfy following
    conditions
  • (1) All locks acquired within the function body
    are released before exiting.
  • (2) No execution paths attempt to lock or
    unlock the same lock twice.
  • (3) Upon exiting, interrupts are either enabled
    or restored to their initial state.
  • (4) The bottom halves of interrupt handlers
    are not disabled upon exiting.
  • (5) Interrupt flags are saved before they are
    restored.
  • We can write metal state-machine to check these
    conditions.

30
Linux Mutual Exclusion 2/2
hold s-gtlock
s-gtlock is not released.
31
Conclusion 1/1
  • Systems are pervaded with restrictions of what
    actions programmers must always or never perform,
    how they must order events, and which actions are
    legal in a given context.
  • Programmers make mistakes, and often have only an
    approximate understanding of important system
    restrictions.
  • Meta-level compilation makes it easy for
    implementers to extend compilers with lightweight
    system-specific checkers.
  • The authors demonstrated meta-level compilations
    power by check real, heavily-used, and test
    systems.

32
References
  • 1 Checking System Rules Using System-Specific,
    Programmer-Written Compiler Extensions
  • by D. Engler et al, OSDI 2000
Write a Comment
User Comments (0)
About PowerShow.com