skip to main content

Leveraging rust types for modular specification and verification

Published:10 October 2019Publication History
Skip Abstract Section

Abstract

Rust's type system ensures memory safety: well-typed Rust programs are guaranteed to not exhibit problems such as dangling pointers, data races, and unexpected side effects through aliased references. Ensuring correctness properties beyond memory safety, for instance, the guaranteed absence of assertion failures or more-general functional correctness, requires static program verification. For traditional system programming languages, formal verification is notoriously difficult and requires complex specifications and logics to reason about pointers, aliasing, and side effects on mutable state. This complexity is a major obstacle to the more-widespread verification of system software.

In this paper, we present a novel verification technique that leverages Rust's type system to greatly simplify the specification and verification of system software written in Rust. We analyse information from the Rust compiler and synthesise a corresponding core proof for the program in a flavour of separation logic tailored to automation. To verify correctness properties beyond memory safety, users can annotate Rust programs with specifications at the abstraction level of Rust expressions; our technique weaves them into the core proof to verify modularly whether these specifications hold. Crucially, our proofs are constructed and checked automatically without exposing the underlying formal logic, allowing users to work exclusively at the level of abstraction of the programming language. As such, our work enables a new kind of verification tool, with the potential to impact a wide audience and allow the Rust community to benefit from state-of-the-art verification techniques. We have implemented our techniques for a subset of Rust; our evaluation on several thousand functions from widely-used Rust crates demonstrates its effectiveness.

Skip Supplemental Material Section

Supplemental Material

a147-astrauskas

Presentation at OOPSLA '19

References

  1. Martìn Abadi and Marcelo Fiore. 1996. Syntactic Considerations on Recursive Types. In Logic in Computer Science (LICS). IEEE Computer Society, 242–252.Google ScholarGoogle Scholar
  2. Vytautas Astrauskas, Peter Müller, Federico Poli, and Alexander J. Summers. 2019a. Artefact containing the prototype implementation. Google ScholarGoogle ScholarDigital LibraryDigital Library
  3. Vytautas Astrauskas, Peter Müller, Federico Poli, and Alexander J. Summers. 2019b. Leveraging Rust Types for Modular Specification and Verification . Technical Report. ETH Zurich.Google ScholarGoogle Scholar
  4. Alexander Bakst and Ranjit Jhala. 2016. Predicate Abstraction for Linked Data Structures. In Verification, Model Checking, and Abstract Interpretation (VMCAI) (Lecture Notes in Computer Science) , Barbara Jobstmann and K. Rustan M. Leino (Eds.), Vol. 9583. Springer, 65–84.Google ScholarGoogle Scholar
  5. Marek Baranowski, Shaobo He, and Zvonimir Rakamarić. 2018. Verifying Rust Programs with SMACK. In Automated Technology for Verification and Analysis (ATVA) (Lecture Notes in Computer Science) , Shuvendu K. Lahiri and Chao Wang (Eds.), Vol. 11138. Springer, 528–535.Google ScholarGoogle Scholar
  6. Mike Barnett, Manuel Fähndrich, K. Rustan M. Leino, Peter Müller, Wolfram Schulte, and Herman Venter. 2011. Specification and Verification: The Spec# Experience. Commun. ACM 54, 6 (June 2011), 81–91.Google ScholarGoogle ScholarDigital LibraryDigital Library
  7. Kevin Bierhoff. 2011. Automated Program Verification Made SYMPLAR: Symbolic Permissions for Lightweight Automated Reasoning. In Symposium on New Ideas, New Paradigms, and Reflections on Programming and Software (Onward! 2011). ACM, 19–32.Google ScholarGoogle ScholarDigital LibraryDigital Library
  8. John Boyland. 2003. Checking Interference with Fractional Permissions. In Static Analysis Symposium (SAS) (Lecture Notes in Computer Science) , Radhia Cousot (Ed.), Vol. 2694. Springer, 55–72.Google ScholarGoogle Scholar
  9. John Boyland, James Noble, and William Retert. 2001. Capabilities for Sharing: A Generalisation of Uniqueness and Read-Only. In European Conference on Object-Oriented Programming (ECOOP) (Lecture Notes in Computer Science), Jørgen Lindskov Knudsen (Ed.), Vol. 2072. Springer, 2–27.Google ScholarGoogle ScholarCross RefCross Ref
  10. Sylvan Clebsch, Sophia Drossopoulou, Sebastian Blessing, and Andy McNeil. 2015. Deny Capabilities for Safe, Fast Actors. In International Workshop on Programming Based on Actors, Agents, and Decentralized Control (AGERE! 2015). ACM, 1–12.Google ScholarGoogle Scholar
  11. Clippy contributors. 2019. Clippy. https://github.com/rust-lang/rust-clippy Accessed April 4, 2019.Google ScholarGoogle Scholar
  12. Ernie Cohen, Markus Dahlweid, Mark A. Hillebrand, Dirk Leinenbach, Michal Moskal, Thomas Santen, Wolfram Schulte, and Stephan Tobies. 2009. VCC: A Practical System for Verifying Concurrent C. In Theorem Proving in Higher Order Logics (TPHOLs) (Lecture Notes in Computer Science) , Stefan Berghofer, Tobias Nipkow, Christian Urban, and Makarius Wenzel (Eds.), Vol. 5674. Springer, 23–42.Google ScholarGoogle Scholar
  13. Coq Team. 2014. The Coq Proof Assistant Reference Manual. http://coq.inria.fr .Google ScholarGoogle Scholar
  14. Karl Crary, Robert Harper, and Sidd Puri. 1999. What is a Recursive Module?. In Programming Language Design and Implementation (PLDI) , Barbara G. Ryder and Benjamin G. Zorn (Eds.). ACM, 50–63.Google ScholarGoogle Scholar
  15. Leonardo Mendonça de Moura, Soonho Kong, Jeremy Avigad, Floris van Doorn, and Jakob von Raumer. 2015. The Lean Theorem Prover (System Description). In Automated Deduction (CADE) (Lecture Notes in Computer Science), Amy P. Felty and Aart Middeldorp (Eds.), Vol. 9195. Springer, 378–388.Google ScholarGoogle Scholar
  16. Robert Dockins, Adam Foltzer, Joe Hendrix, Brian Huffman, Dylan McNamee, and Aaron Tomb. 2016. Constructing Semantic Models of Programs with the Software Analysis Workbench. In Verified Software. Theories, Tools, and Experiments (VSTTE) (Lecture Notes in Computer Science) , Sandrine Blazy and Marsha Chechik (Eds.), Vol. 9971. 56–72.Google ScholarGoogle Scholar
  17. J. Nathan Foster, Michael B. Greenwald, Jonathan T. Moore, Benjamin C. Pierce, and Alan Schmitt. 2005. Combinators for Bi-directional Tree Transformations: A Linguistic Approach to the View Update Problem. SIGPLAN Not. 40, 1 (Jan. 2005), 233–246.Google ScholarGoogle ScholarDigital LibraryDigital Library
  18. Jean-Yves Girard. 1987. Linear Logic. Theor. Comput. Sci. 50, 1 (Jan. 1987), 1–102.Google ScholarGoogle ScholarDigital LibraryDigital Library
  19. Colin S. Gordon, Matthew J. Parkinson, Jared Parsons, Aleks Bromfield, and Joe Duffy. 2012. Uniqueness and Reference Immutability for Safe Parallelism. SIGPLAN Not. 47, 10 (Oct. 2012), 21–40.Google ScholarGoogle ScholarDigital LibraryDigital Library
  20. Florian Hahn. 2015. Rust2Viper: Building a static verifier for Rust. Master’s thesis. ETH Zurich.Google ScholarGoogle Scholar
  21. Philipp Haller and Martin Odersky. 2010. Capabilities for Uniqueness and Borrowing. In European Conference on ObjectOriented Programming (ECOOP) (Lecture Notes in Computer Science) , Theo D’Hondt (Ed.), Vol. 6183. Springer, 354–378.Google ScholarGoogle Scholar
  22. Chris Hawblitzel, Jon Howell, Manos Kapritsos, Jacob R. Lorch, Bryan Parno, Michael L. Roberts, Srinath Setty, and Brian Zill. 2015. IronFleet: Proving Practical Distributed Systems Correct. In Symposium on Operating Systems Principles (SOSP), Ethan L. Miller and Steven Hand (Eds.). ACM, 1–17.Google ScholarGoogle ScholarDigital LibraryDigital Library
  23. Chris Hawblitzel, Jon Howell, Jacob R. Lorch, Arjun Narayan, Bryan Parno, Danfeng Zhang, and Brian Zill. 2014. Ironclad Apps: End-to-End Security via Automated Full-System Verification. In Operating Systems Design and Implementation (OSDI) , Jason Flinn and Hank Levy (Eds.). USENIX Association, 165–181.Google ScholarGoogle Scholar
  24. Stefan Heule, K. Rustan M. Leino, Peter Müller, and Alexander J. Summers. 2013. Abstract Read Permissions: Fractional Permissions without the Fractions. In Verification, Model Checking, and Abstract Interpretation (VMCAI) (Lecture Notes in Computer Science) , Vol. 7737. Springer, 315–334.Google ScholarGoogle Scholar
  25. Cliff B. Jones. 1983. Specification and design of (parallel) programs. In IFIP Congress. 321–332.Google ScholarGoogle Scholar
  26. Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers, and Derek Dreyer. 2018. RustBelt: Securing the Foundations of the Rust Programming Language. PACMPL 2, POPL (2018), 66:1–66:34.Google ScholarGoogle ScholarDigital LibraryDigital Library
  27. Ralf Jung, David Swasey, Filip Sieczkowski, Kasper Svendsen, Aaron Turon, Lars Birkedal, and Derek Dreyer. 2015. Iris: Monoids and Invariants as an Orthogonal Basis for Concurrent Reasoning. ACM SIGPLAN Notices 50, 1 (2015), 637–650.Google ScholarGoogle ScholarDigital LibraryDigital Library
  28. Shuanglong Kan, David Sanán, Shang-Wei Lin, and Yang Liu. 2018. K-Rust: An Executable Formal Semantics for Rust. CoRR abs/1804.07608 (2018). arXiv: 1804.07608 http://arxiv.org/abs/1804.07608Google ScholarGoogle Scholar
  29. Ioannis T. Kassios. 2011. The Dynamic Frames Theory. Formal Aspects of Computing 23, 3 (2011), 267–289.Google ScholarGoogle ScholarDigital LibraryDigital Library
  30. Gerwin Klein, Kevin Elphinstone, Gernot Heiser, June Andronick, David Cock, Philip Derrin, Dhammika Elkaduwe, Kai Engelhardt, Rafal Kolanski, Michael Norrish, Thomas Sewell, Harvey Tuch, and Simon Winwood. 2009. seL4: Formal Verification of an OS Kernel. In Symposium on Operating Systems Principles (SOSP), Jeanna Neefe Matthews and Thomas E. Anderson (Eds.). ACM, 207–220.Google ScholarGoogle ScholarDigital LibraryDigital Library
  31. Gary T. Leavens, Erik Poll, Curtis Clifton, Yoonsik Cheon, Clyde Ruby, David Cok, Peter Müller, Joseph Kiniry, Patrice Chalin, Daniel M. Zimmerman, and Werner Dietl. 2011. JML Reference Manual. http://www.jmlspecs.org/ .Google ScholarGoogle Scholar
  32. K. Rustan M. Leino. 2010. Dafny: An Automatic Program Verifier for Functional Correctness. In Logic for Programming, Artificial Intelligence, and Reasoning (LPAR) (Lecture Notes in Computer Science) , Edmund M. Clarke and Andrei Voronkov (Eds.), Vol. 6355. Springer, 348–370.Google ScholarGoogle Scholar
  33. K. Rustan M. Leino and Peter Müller. 2004. Object Invariants in Dynamic Contexts. In European Conference on Object-Oriented Programming (ECOOP) (Lecture Notes in Computer Science) , M. Odersky (Ed.), Vol. 3086. Springer, 491–516.Google ScholarGoogle Scholar
  34. K. Rustan M. Leino and Greg Nelson. 2002. Data Abstraction and Information Hiding. ACM Trans. Program. Lang. Syst. 24, 5 (2002), 491–553.Google ScholarGoogle ScholarDigital LibraryDigital Library
  35. Marcus Lindner, Jorge Aparicius, and Per Lindgren. 2018. No Panic! Verification of Rust Programs by Symbolic Execution. In Industrial Informatics (INDIN). IEEE, 108–114.Google ScholarGoogle Scholar
  36. Maroua Maalej, Tucker Taft, and Yannick Moy. 2018. Safe Dynamic Memory Management in Ada and SPARK. (2018).Google ScholarGoogle Scholar
  37. Nicholas D. Matsakis. 2018a. MIR-based borrow check (NLL) status update. http://smallcultfollowing.com/babysteps/blog/ 2018/06/15/mir-based-borrow-check-nll-status-update Accessed April 4, 2019.Google ScholarGoogle Scholar
  38. Nicholas D. Matsakis. 2018b. MIR-based borrowck is almost here. http://smallcultfollowing.com/babysteps/blog/2018/10/ 31/mir-based-borrowck-is-almost-here/ Accessed April 4, 2019.Google ScholarGoogle Scholar
  39. Nicholas D. Matsakis and Felix S. Klock II. 2014. The Rust language. In ACM SIGAda Ada Letters, Vol. 34. ACM, 103–104.Google ScholarGoogle Scholar
  40. Bertrand Meyer. 1992. Design by Contract. In Advances in object-oriented software engineering, Dino Mandrioli and Bertrand Meyer (Eds.). Prentice Hall, 1–50.Google ScholarGoogle Scholar
  41. P. Müller. 2002. Modular Specification and Verification of Object-Oriented Programs. Lecture Notes in Computer Science, Vol. 2262. Springer.Google ScholarGoogle ScholarCross RefCross Ref
  42. Peter Müller, Malte Schwerhoff, and Alexander J. Summers. 2016. Viper: A Verification Infrastructure for Permission-Based Reasoning. In VMCAI (Lecture Notes in Computer Science), Barbara Jobstmann and K. Rustan M. Leino (Eds.), Vol. 9583. Springer, 41–62.Google ScholarGoogle Scholar
  43. Peter W. O’Hearn. 2004. Resources, Concurrency and Local Reasoning. In Concurrency Theory (CONCUR) (Lecture Notes in Computer Science) , Philippa Gardner and Nobuko Yoshida (Eds.), Vol. 3170. Springer, 49–67.Google ScholarGoogle Scholar
  44. Peter W. O’Hearn, John C. Reynolds, and Hongseok Yang. 2001. Local Reasoning about Programs that Alter Data Structures. In Computer Science Logic (CSL) (Lecture Notes in Computer Science), Laurent Fribourg (Ed.), Vol. 2142. Springer, 1–19.Google ScholarGoogle Scholar
  45. Susan Owicki and David Gries. 1976. Verifying Properties of Parallel Programs: An Axiomatic Approach. Commun. ACM 19, 5 (May 1976), 279–285.Google ScholarGoogle ScholarDigital LibraryDigital Library
  46. Matthew J. Parkinson and Gavin M. Bierman. 2005. Separation logic and abstraction. In Principles of Programming Languages (POPL) , Jens Palsberg and Martín Abadi (Eds.). ACM, 247–258.Google ScholarGoogle Scholar
  47. Matthew J. Parkinson and Alexander J. Summers. 2012. The Relationship Between Separation Logic and Implicit Dynamic Frames. Logical Methods in Computer Science 8, 3:01 (2012), 1–54.Google ScholarGoogle ScholarCross RefCross Ref
  48. Eric W. Reed. 2015. Patina: A Formalization of the Rust Programming Language. Technical Report UW-CSE-15-03-02. University of Washington.Google ScholarGoogle Scholar
  49. John C. Reynolds. 2002. Separation Logic: A Logic for Shared Mutable Data Structures. In Logic in Computer Science (LICS). IEEE Computer Society, 55–74.Google ScholarGoogle Scholar
  50. Patrick M. Rondon, Ming Kawaguci, and Ranjit Jhala. 2008. Liquid Types. SIGPLAN Not. 43, 6 (June 2008), 159–169.Google ScholarGoogle ScholarDigital LibraryDigital Library
  51. Rosetta Code contributors. 2018. Rosetta Code. https://rosettacode.org/wiki/Category:Rust Accessed November 5, 2018.Google ScholarGoogle Scholar
  52. Rust community. 2017. Non-Lexical Lifetimes RFC. https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md Accessed November 4, 2018.Google ScholarGoogle Scholar
  53. Rust community. 2018a. The Rust community’s crate registry. https://crates.io Downloaded on November 2, 2018.Google ScholarGoogle Scholar
  54. Rust community. 2018b. Rust: The Reference — Place Expressions and Value Expressions. https://doc.rust-lang.org/ reference/expressions.html#place-expressions-and-value-expressions Accessed November 4, 2018.Google ScholarGoogle Scholar
  55. Rust community. 2019. Learn Rust by writing Entirely Too Many Linked Lists. https://rust-unofficial.github.io/too-manylists/first-final.html Accessed April 4, 2019.Google ScholarGoogle Scholar
  56. Rust contributors. 2019a. The Polonius Reference Implementation for the Rust Borrow-Checker. https://github.com/rustlang/polonius Accessed April 4, 2019.Google ScholarGoogle Scholar
  57. Rust contributors. 2019b. The Rustonomicon: Working with Unsafe. https://doc.rust-lang.org/nomicon/working-withunsafe.html Accessed April 4, 2019.Google ScholarGoogle Scholar
  58. Rust contributors. 2019c. Tracking issue for generalized two-phase borrows. https://github.com/rust-lang/rust/issues/49434 Accessed April 4, 2019.Google ScholarGoogle Scholar
  59. Malte Schwerhoff and Alexander J. Summers. 2015. Lightweight Support for Magic Wands in an Automatic Verifier. In European Conference on Object-Oriented Programming (ECOOP) (LIPIcs) , J. T. Boyland (Ed.), Vol. 37. Schloss Dagstuhl, 614–638.Google ScholarGoogle Scholar
  60. Jan Smans, Bart Jacobs, and Frank Piessens. 2009. Implicit Dynamic Frames: Combining Dynamic Frames and Separation Logic. In European Conference on Object-Oriented Programming (ECOOP) (Lecture Notes in Computer Science), Sophia Drossopoulou (Ed.), Vol. 5653. Springer, 148–172.Google ScholarGoogle Scholar
  61. Jan Smans, Bart Jacobs, and Frank Piessens. 2010. Heap-Dependent Expressions in Separation Logic. In Formal Techniques for Distributed Systems (FMOODS/FORTE) (Lecture Notes in Computer Science) , John Hatcliff and Elena Zucca (Eds.), Vol. 6117. Springer, 170–185.Google ScholarGoogle Scholar
  62. Sven Stork, Karl Naden, Joshua Sunshine, Manuel Mohr, Alcides Fonseca, Paulo Marques, and Jonathan Aldrich. 2014. AEMinium: A Permission-Based Concurrent-by-Default Programming Language Approach. ACM Trans. Program. Lang. Syst. 36, 1 (March 2014), 2:1–2:42.Google ScholarGoogle ScholarDigital LibraryDigital Library
  63. Alexander J. Summers and Sophia Drossopoulou. 2013. A Formal Semantics for Isorecursive and Equirecursive State Abstractions. In European Conference on Object-Oriented Programming (ECOOP) (Lecture Notes in Computer Science), Giuseppe Castagna (Ed.), Vol. 7920. Springer, 129–153.Google ScholarGoogle Scholar
  64. John Toman, Stuart Pernsteiner, and Emina Torlak. 2015. Crust: A Bounded Verifier for Rust (N). In Automated Software Engineering (ASE) , Myra B. Cohen, Lars Grunske, and Michael Whalen (Eds.). IEEE, 75–80.Google ScholarGoogle Scholar
  65. Sebastian Ullrich. 2016. Simple Verification of Rust Programs via Functional Purification. Master’s thesis. Karlsruhe Institute of Technology.Google ScholarGoogle Scholar
  66. Feng Wang, Fu Song, Min Zhang, Xiaoran Zhu, and Jun Zhang. 2018. KRust: A Formal Executable Semantics of Rust. CoRR abs/1804.10806 (2018). arXiv: 1804.10806 http://arxiv.org/abs/1804.10806Google ScholarGoogle Scholar
  67. Aaron Weiss, Daniel Patterson, and Amal Ahmed. 2018. Rust Distilled: An Expressive Tower of Languages. arXiv preprint arXiv:1806.02693 (2018).Google ScholarGoogle Scholar

Index Terms

  1. Leveraging rust types for modular specification and verification

                Recommendations

                Comments

                Login options

                Check if you have access through your login credentials or your institution to get full access on this article.

                Sign in

                Full Access

                PDF Format

                View or Download as a PDF file.

                PDF

                eReader

                View online with eReader.

                eReader
                About Cookies On This Site

                We use cookies to ensure that we give you the best experience on our website.

                Learn more

                Got it!