<<

The SLAM Project: System via Static Analysis*

Thomas Ball and Sriram K. Rajamani {tball,sriram}@microsoft.com Microso~ Research http://research.microsoft.com/slam/

Abstract. The goal of the SLAM project is to check whether automaton can read (but not modify) the state of the or not a program obeys "API usage rules" that specif[y what program that is visible at the function call/return interface, it means to be a good client of an API. The SLAM toolkit maintain a history, and signal when a bad state occurs. }V~ statically analyzes a C program to determine whether or have developed Smc specifications for a variety of Windows not it violates given usage rules. The toolkit has two unique XP driver properties, ranging from simple locking proper- aspects: it does not require the to annotate ties (such as given above) to complex properties dealing with the source program (invariants are inferred); it minimizes completion routines, plug-and-play, and power management. noise (false error messages) through a process known as Given a program P and a Sac specification S, a pre- "counterexample-driven refinement". SLAM exploits and ex- processor creates an instrumented program P' such that a tends results fi'om , model checking and au- unique ERROR is reachable in P' if-and-only-if P does tomated deduction. }V~ have successfully applied the SLAM not satisI} S. The goal then shifts to determining whether toolkit to Windows XP device drivers, to both validate be- or not the ERROR label is reachable in P', a generally unde- havior and find defects in their usage of kernel APIs. cidable problem.

Context. Today, many are realizing the ben- Design. The design of the SLAM process is to iterate efits of using languages with static type systems. By pro- the creation, analysis and refinement of program abstrac- viding simple specifications about the tbrm of program data, tions, until either a t~asible execution path in P' to ERROR programmers receive useful compile-time error messages or is tbund~ the prograln P' is validated (EEROR is shown not guarantees about the behavior of their (type-correct) pro- to be reachable), or we run out of resources or patience. grams. Getting additional checking beyond the confines of The SLAM process creates a sound boolears pr~gr~rrs ab- a particular generally requires programmers to straction B' of the C program p,.1 Boolean programs have use assertions and pertbrm testing. A number of projects all the control-flow constructs of C programs, but contain have started to tbcus on statically checking programs against only boolean variables. Each boolean variable in B' con- user-supplied specifications, using techniques from program servatively tracks the state of a predicate (boolean expres- analysis [18, 19], model checking [21, 17, 22], and automated sion) in the C program. Boolean programs are created au- deduction [16, 12]. tomatically using the technique of predicate abstr~ctior~ [20]. If a teachability analysis of B' determines that the label Specification. The goal of the SLAM project is to check ERROR is not reachable in B' then it is not reachable in temporal sat>ty properties of sequential C programs [7]. P'. It is possible that B' may be too coarse an abstrac- Roughly stated, temporal sat~ty properties are those proper- tion of P' (that is, ERROR is reachable in B' via a path p ties whose violation is witnessed by a finite execution trace but ERROR is not reachable in P' via p). V~ apply a method (see [24] ibr a formal definition). A simple example of a known as cour~terw'arr~ple-driver~ ~vfir~err~er~t [23, 28, 27] to sat>ty property is that a lock should be alternatingly ac- create a more precise boolean program (by adding new pred- quired and released. }¥~ encode temporal sat~ty properties icates/boolean variables) that does not contain the spurious in a language called Sac (Specification Language for Inter- path p (or other paths that are spurious tbr the same reason face Checking) [9], which allows the definition of a sat~ty p is). Termination of the SLAM process is addressed below. automaton [30, 29] that monitors the execution behavior of }V~ expect the SLAM process to work well tbr programs a program at the level of function calls and returns. The whose behavior is governed by an underlying finite state pro- tocol. Seen in this light, the goal of SLAM is tO tease out *Presented by the first author. the underlying "protocol" state machine ti'om the code, to Permission to make digital or hard copies of all or part a level of precision that is good enough to find real errors of this work for personal or classroom use is granted with- out fee provided that copies are not made or distributed for 1Of course, whenever one hears a claim that an analysis of C code profit or commercial advantage and that copies bear this no- is %ound", one must ask %ound with respect to what assumptions'.'" tice and the full citation on the first page. 2b copy oth- because of the (potential) use of arbitrary pointer arithmetic. In erwise, to republish, to post on servers or to redistribute SLAM, %ve guarantee soundness under the assumption that the C pro- gram obeys a "logical memory model' in which the expressions *p and to lists, requires prior specific permission and/or at fee. *(p+i) refer to the same object. Another analysis (see the work on POPL '02, Jan. 16-18, 2002 Portland, OR USA CCured presented at this symposium [25]) is needed to discharge the Copyright 2002 ACM ISBN 1-58113-450-9/02/01...$5.00 "logical memory" assumption.

1

or validate the code. For example, while a video card driver In practice, the SLAM process has terminated for all may have a huge data path, most of this data has no bearing drivers within 20 iterations. Our major concern has been on the driver's interaction with the operating system. How- with the overall running time of the process. So far, we are ever, some of the driver data definitely are relevant to this able to analyze programs on the order of 10,000 lines, and interaction, and correlations between these data may need abstractions with several hundred boolean variables in the to be tracked. range of minutes to a half hour. In practice, we find that most of the predicates SLAM generates are simple equalities Implementation. Three basic tools comprise the SLAM with possible pointer deret~rences. For this class of predi- toolkit (in addition to the SLI¢ preprocessor): cates, we believe it is possible to scale the SLAM process to several 100,000 lines of code through optimizations outlined • C2Be, a tool that transtbrms a C program P into a below. boolean program /31P(P,E) with respect to a set of A major expense in the SLAM process is the reacha- predicates E [2, 3]. C2Bp translates each procedure bility step (BEgot'), which has worst case running time of the C program separately, enabling it to scale to O(N(GL)a), where N is the size of the boolean program, G large programs. Using the theory of abstract interpre- is the number of global states, and L is the maximum num- tation [13], we have characterized the precision of the ber of local states over all procedures. The number of states boolean program abstractions created by C2ge [4]. is exponential (in the worst-case) in the maximal number of • BEBOP, a too1 for performing reachability analysis of variables in scope. boolean programs [6, 8]. BEBOe combines interproce- The key to scaling for the SLAM process is in control- dural dataflow analysis in the style of [26] with Binary ling the complexity of the boolean program abstraction. Decision Diagrams [10, 11] (BDDs) to etficiently rep- Satyaki Das has implemented a predicate abstraction tech- resent the reachable states of the boolean program at nique based on successive approximations [15] in the SLAM each program point. toolkit, which has proven quite useful in this regard. Also relevant here is the paper on "lazy abstraction" in this sym- • NEWTON, a too1 that discovers additional predicates to posium [21]. refine the boolean program, by analyzing the t~asibility Additionally, there is substantial overhead in having to of paths in the C program. iterate the SLAM process many times, which can be ad- dressed by both the "lazy abstraction" method as well as The SLAM process starts with an initial set of predicates E0 methods tbr heuristically determining a "good" initial set derived t¥om the SLI¢ specification, and iterates the follow- of predicates. }V~stley }V~imer has implemented an algo- ing steps: rithm in SLAM that, given the set of predicates present in 1. Apply C2BP to construct the boolean program the SLI¢ specification, determines what other predicates in 13p(P', Ed. the C program will very likely be needed in the future. This technique, based on the value-flow graph [14], greatly re- 2. Apply BEBOe to check if there is a path Pi in duces the number of iterations of the SLAM process. BT'(P', Ei) that reaches the ERROR label. If BEBOP de- termines that ERROR is not reachable, then P satisfies Challenges, ~¥~ summarize by discussing some of the chal- the SLI¢ specification and the process terminates. lenges inherent in the endeavor of checking user-supplied properties of sottware. 3. If there is such a path pi, then NEWTON checks if Pi is feasible in P'. There are three possible outcomes: Specification burden. The creation of correct specifications "yes", the process terminates with an error path pi; is a hard problem requiring human time and energy (in the "no", in which case NEWTON finds a set of predicates extreme, it is as hard as writing a program). If the effort FFi that "explain" the ini~asibility of path pi in P'; put into developing specifications is not paid back in terms "maybe", the incompleteness of the underlying theo- of discovered detects, then there is little incentive to develop rem prover may cause this outcome, in which case user specifications in the first place. }V~ focused our specification input is required. effort at the level of the API so that specifications may be reused across different programs using the API. SLI¢ spec- 4. Let E/+l := E/U FFs, and i := i + 1, and proceed to the ifications can be partial. V~ started by first specit~ing a next iteration. small set of errors in SLI¢, and then gradually enlarging the set. Nevertheless, the complexity of the API Termination: Theory and Practice. }V~ have proved a meant that it took considerable eflbrt to arrive at a use- strong relationship between a process based on iterative re- ful specification that tbund real detects. The "chicken and finement of abstractions (such as in SLAM) and traditional egg" problem of specifications is the topic of a paper in this fixpoint analyses with widening (which is used to ensure symposium [1]. the termination of abstract interpretations in domains with infinite ascending chains) [5]. Using widening, the latter Annotation burden. By "annotation", we mean a modifica- process always will terminate, but it may not give a defi- tion to the program text inserted by a programmer explic- nite result ("error found" or "program validated"). ~V~ have itly to help an analysis tool make progress. Examples of shown that if there is an oracle that can provide a "widening such annotations include loop invariants and pre- and post- schedule" that causes the latter method to terminate with conditions for procedures, such as required by the ESC-Java a definite result then an iterative refinement process (which tool [16]. In SLAM, annotations are not required. Instead, does not rely on an oracle) will terminate with a definite the abstract fixpoint analysis of the BEBOP too1 discovers result. Intuitively, this means that iterative refinement has inductive invariants (loop invariants as well as procedure the eft>ct of exploring the entire state space of all possible call summaries) expressed as a boolean combination of the sequences of widenings. predicates that are input to the C2BP tool.

2

Ou@ut. Generating good explanations of errors and their [7] T. Ball and S. K. Ru,ju,nlu, ni. AutomaticMly validating temporM causes is a complicated affair, made more difficult as the sM'ety properties of interfaces. In SPIN 01: 5'PIN Workshop, expressivity of the specification language increases. When LNCS 20557, pages 103 122. Springer-Verlag, 2001. the SLAM toolkit finds an error, it presents it as an error [8] T. Ball and S. K. Ru.ju.Inani. Bebop: A path-sensitive interpro- cedural dataflow engine. In PAb'TE 01: Workshop on Program path in the using an interface that resembles Anelysis fur b'@w~re 2bols ~nd ET~~eeriT~9, pages 97 103. a source level . However, there is sometimes an ACM, 2001. overwhelming amount of detail in these traces. }¥~ are de- [9] T. Ball and S. K. Rajamani. SLIC: A specification language veloping techniques for presenting both short and detailed tbr interface checking. TechnicM Report MSR-TR-2001-21, Mi- summaries of errors. crosot% Research, 2001. [10] R. Bryant. Graph-based algorithms tbr boolean function manip- Soundness~Completeness~Usefulness. An analysis is ulation. 1EEE 2}'ansactions on Cow,parers, C-35(8):677 691, %ound" if every true error is reported by the analysis, "com- 1986. plete" if every reported error is a true error (no noise), [11] J. Burch, 19. Clarke, K. McMillan, D. Dill, and L. tiwang. Sym- and "use%l" if it finds errors that someone (programmers, bolic model checking: 102° states and beyond. Information and testers, customers) cares about. Detbct detection tools such Computation, 98(2):142 170, 1992. as LCLint [19], Metal [18] and PREfix [12] are neither sound [12] YV. I~. Bush, J. D. Pincus, and D. J. Sielaff. A static analyzer tbr finding dynamic programming errors, b'@ware-Prac~ice and nor complete, yet are demonstrably useful. SLAM is sound Experience, 30(7):775 802, June 2000. (relative to the assumptions stated before), incomplete and [13] P. Cousot and I~. Cousot. : a unified is starting to demonstrate usefulness in the domain of device lattice model for the static analysis of programs by construc- drivers. tion or approximation of fixpoints. In POPL 77: Principles of Progr~ing Languages, pages 238 252. ACM, 1977. Acknowledgements. Many people have contributed to [14] M. Das. Unification-based pointer analysis with directional as- the SLAM project. V~ have been fortunate to have many signInents. In PLD1 00: Progra~ing Language Design and excellent interns who helped push the project forward over Implementation, pages 35 46. ACM, 2000. [15] S. Das and D. L. Dill. Successive approximation of abstract trail- the summer months of 2000 and 2001. Sagar Chaki, Rupak sition relations. In LJC'S 01: b'y~posiu~ on Logic i7~ C'on~puter Majumdar and Todd Millstein were 2000 summer interns. b'cieT~ce, 2001. Sagar Chaki, Satyaki Das, Robby and }¥~stley }¥~imer were [16] D. L. Detlet%, K. I~. M. Leino, G. Nelson, and J. B. Saxe. l~x- 2001 summer interns. V~ have had a long and fYuitful col- tended static checking. TechnicM Igeport l~esearch Igeport 159, laboration with Andreas Podelski, who has helped us un- CoInpaq Systems Igesearch Center, December 1998. derstand the theoretical limits of the SLAM approach. [17] M. Dwyer, J. tiatcliff, I~. Joehanes, S. Laubach, C. Pasareanu, The SLAM toolkit would not be possible without the soft- l~obby, VV. Visser, and It. Zheng. Tool-supported program ab- straction for finite-state verification. In 1USE 01: b'@w~re En- ware it builds upon. V~ thank Manuvir Das for providing gineering, pages 177 187, 2001. us his one-level flow analysis tool. }¥~ thank the develop- [18] D. l~ngler, B. Chelf, A. Chou, and S. tiallem. Checking system ers of the AST toolkit at Microsot% Research, and Manuel rules using system-specific, programmer-written exten- Fghndrich for providing us his OCaml interface to the AST sions. In Oh'D1 00: (gpera~ing b'ys~e~ DesigT~ aT~d l~p~e~en- toolkit. Additionally, we have made good use of the publi- ~gion. Usenix Association, 2000. cally available OCaml language, the Simpli[v and Vampyre [19] D. l~vans. Static detection of dynamic memory errors. In PLD1 '96, pages 44 53. ACM, May 1996. theorem provers, and the BDD libraries of CMU and Col- [20] S. Graf and It. Sa;fdi. Construction of abstract state graphs with orado. PVS. In C'AV P7: Cow,purer Aided Verijic~ion, LNCS 1254, Thanks also to the members of the Sot%ware Productiv- pages 72 83. Springer-Verlag, 1997. ity Tools research group at Microsot% Research tbr many [21] T. A. tienzinger, I~. Jhala, I~. Majumdar, and G. Sutre. Lazy enlightening discussions on program analysis, programming abstraction. In POPL '02. ACM, January 2002. languages and device drivers. Finally, thanks to Jim Larus, [22] G. tIolzmann. Logic verification of ANSI-C code with Spin. who initially suggested device drivers as an interesting ap- In SP1N 00: SP1N Workshop, LNCS 1885, pages 131 147. Springer- Verlag, 2000. plication domain. [23] I%. Kurshan. Co~pu~er-eided Verijic~ion of Coordinating Pro- cesses. Princeton University Press, 1994. References [24] L. Lamport. Proving the correctness of multiprocess programs. 1EEE 2}'ansactions on b'@ware Engineering, S19-3(2):125 143, [1] G. AInInons, ]~. Bodik, and J. I~. Larus. Mining specifications. In POPL '02. ACM, January 2002. 1977. [25] G. Necula, S. McPeak, and VV. YVeinler. CCured: Type-sM:e [2] T. Ball, I~. Majumdar, T. Millstein, and S. K. l~ajamani. Auto- retrofitting of legacy code. In POPL '02. ACM, January 2002. marie predicate abstraction of C programs. In PLD1 01: Pro- gr~i~9 L~gu~ge Desig~ ~d l~p~e~e~t~tio~, pages 203 [26] T. l~eps, S. ttorwitz, and M. Sagiv. Precise interprocedural 213. ACM, 2001. dataflow analysis via graph reachability. In POPL PS: Prin- ciples of Progr~i~9 L~gu~ges, pages 49 61. ACM, 1995. [3] T. Ball, T. Millstein, and S. K. l~ajamani. Polymorphic predi- [27] V. l~usu and 1~. Singerman. Oil proving safety properties by in- cate abstraction. Technical Igeport MSIg-TI%-2001-10, Microsot~ tegrating static analysis, theorem proving and abstraction. In Igesearch, 2001. TAUAS PP: :lbo~s ~nd Algorithms for Uons~ruc~ion ~nd Anal- [4] T. Ball, A. Podelski, and S. K. l~ajamani. Boolean and carte- ysis of System, s, LNCS 1579, pages 178 192. Springer-Verlag, sian abstractions for model checking C programs. In TAUAS 1999. 01: :Ibo~s and Algorithms fur Construction ~nd Analysis of [28] It. Sa:{di and N. Shanhm Abstract and model check while you System, s, LNCS 2031, pages 268 283. Springer-Verlag, 2001. prove. In C'AV PP: C'o~pu~er-~ided Verijic~ion, LNCS 1633, [5] T. Ball, A. Podelski, and S. K. l~ajamani. Oil the relative com- pages 443 454. Springer-Verlag, 1999. pleteness of abstraction refinement. Technical l~eport MSI~-TI~- [29] F. B. Schneider. Enforceable security policies. ACM :I~'ansac- 2001-106, Microsott Igesearch, 2001. ~ions on lnfor~ion ~nd 5'ys~e~ 5'ecuri~y, 3(1):30 50, Febru- ary 2000. [6] T. Ball and S. K. ttajamani. Bebop: A symbolic model checker tbr Boolean programs. In SPIN 00: SPIN Workshop, LNCS [30] M. Y. Vardi and P. YVolper. An automata theoretic apporach to 1885, pages 113 130. Springer-Verlag, 2000. automatic program verification. In L1US 86: Logic in C'o~puter Scie~ce, pages 332 344. I191919 Computer Society Press, 1996.

3