Phd-Manuscript.Pdf
Total Page:16
File Type:pdf, Size:1020Kb
Préparée à l'École Normale Supérieure Analyse de la sécurité de systèmes critiques embarqués à forte composante logicielle par interprétation abstraite Proving the security of software-intensive embedded systems by abstract interpretation Soutenue par Composition du jury : Marc Chevalier Patrick Cousot Le vendredi 27 novembre 2020 Professor, New York University, USA Président Jérôme Feret Chargé de recherche, INRIA, France Directeur de thèse École doctorale no386 Sciences Mathématiques Isabella Mastroeni Associate Professor, Università degli Rapporteuse de Paris Centre Studi di Verona, Italie Peter Müller Professor, ETH Zürich, Suisse Examinateur Spécialité David Pichardie Informatique Professeur, École Normale Supérieure Rapporteur de Rennes, France Marc Pouzet Professeur, École Normale Supérieure, Examinateur France Sukyoung Ryu Associate Professor, KAIST, Corée du Examinatrice Sud Mihaela Sighireanu Maîtresse de conférences HDR, IRIF, Examinatrice France Abstract his thesis is dedicated to the analysis of low-level software, like operating systems, T by abstract interpretation. Analyzing OSes is a crucial issue to guarantee the safety of software systems since they are the layer immediately above the hardware and that all applicative tasks rely on them. For critical applications, we want to prove that the OS does not crash, and that it ensures the isolation of programs, so that an untrusted program cannot disrupt a trusted one. The analysis of this kind of programs raises specific issues. This is because OSes must control hardware using instructions that are meaningless in ordinary programs. In addition, because hardware features are outside the scope of C, source code includes assembly blocks mixed with C code. These are the two main axes in this thesis: handling mixed C and assembly, and precise abstraction of instructions that are specific to low- level software. This work is motivated by the analysis of a case study emanating from an industrial partner, which required the implementation of proposed methods in the static analyzer Astrée. The first part is about the formalization of a language mixing simplified modelsofC and assembly, from syntax to semantics. This specification is crucial to define whatis legal and what is a bug, while taking into account the intricacy of interactions of C and assembly, in terms of data flow and control flow. The second part is a short introduction to abstract interpretation focusing on what is useful thereafter. The third part proposes an abstraction of the semantics of mixed C and assembly. This is actually a series of parametric abstractions handling each aspect of the semantics. The fourth part is interested in the question of the abstraction of instructions specific to low-level software. Interest properties can easily be proven using ghost variables, but because of technical reasons, it is difficult to design a reduced product of abstract domains that allows a satisfactory handling of ghost variables. This part builds such a general framework with domains that allow us to solve our problem and many others. The final part details properties to prove in order to guarantee isolation of programs that have not been treated since they raise many complicated questions. We also give some suggestions to improve the product of domains with ghost variables introduced in the previous part, in terms of features and performances. i ii ABSTRACT Résumé ette thèse est consacrée à l’analyse de logiciels de bas niveau, tels que les systèmes C d’exploitation, par interprétation abstraite. L’analyse des OS est une question im- portante pour garantir la sûreté des systèmes logiciels puisqu’ils forment le niveau immé- diatement au dessus du matériel et que toutes les tâches applicatives dépendent d’eux. Pour des applications critiques, on veut s’assurer que l’OS ne plante pas, mais aussi qu’il assure l’isolation des programmes, de sorte qu’un programme dont la fiabilité n’a pas été établie ne puisse perturber un programme de confiance. L’analyse de ce genre de programmes soulève des problèmes spécifiques. Cela provient du fait que les OS doivent contrôler le matériel avec des opérations qui n’ont pas de sens dans un programme ordinaire. De plus, comme les fonctionnalités matérielles sont en dehors du for du C, le code source contient des blocs de code assembleur mêlés au C. Ce sont les deux axes de cette thèse : gérer les mélanges de C et d’assembleur, et abstraire finement les opérations spécifiques aux logiciels de bas niveau. Ce travail est guidépar l’analyse d’un cas d’étude d’un partenaire industriel, ce qui a nécessité l’implémentation des méthodes proposées dans l’analyseur statique Astrée. La première partie s’intéresse à la formalisation d’un langage mélangeant des mo- dèles simplifiés du C et de l’assembleur, depuis la syntaxe jusqu’à la sémantique. Cette spécification est importante pour définir ce qui est légal et ce qui constitue uneerreur, tout en tenant compte de la complexité des interactions du C et de l’assembleur, tant en termes de données que de flot de contrôle. La seconde partie est une introduction sommaire à l’interprétation abstraite qui se limite à ce qui est utile par la suite. La troisième partie propose une abstraction de la sémantique des mélanges de C et d’assembleur. Il s’agit en fait d’une collection d’abstractions paramétriques qui gèrent chacun des aspects de cette sémantique. La quatrième partie s’intéresse à l’abstraction des opérations spécifiques aux logiciels de bas niveau. Les propriétés d’intérêt peuvent être facilement prouvées à l’aide de variables fantômes, mais pour des raisons techniques, il est difficile de concevoir un produit réduit de domaines abstraits qui supporte une gestion satisfaisante des variables fantômes. Cette partie construit un tel cadre très général ainsi que des domaines qui permettent de résoudre beaucoup de problèmes dont le nôtre. L’ultime partie présente quelques propriétés à prouver pour garantir l’isolation des programmes, qui n’ont pas été traitées car elles posent de nouvelles et complexes ques- iii iv RÉSUMÉ tions. On donne aussi quelques propositions d’amélioration du produit de domaines avec variables fantômes introduit dans la partie précédente, tant en termes de fonctionnalités que de performances. Contents Abstract i Résumé iii Contents v 1 Introduction 1 1.1 Context . 2 1.2 Motivation . 3 1.3 Overview . 4 2 The x86 Architecture and System Programming 7 2.1 An Overview of the x86 Architecture . 7 2.1.1 A Piece of History . 7 2.1.2 Characteristics of the 32-bit x86 Architecture . 8 2.1.3 Conventions . 9 2.2 Execution Environment . 10 2.2.1 Registers . 10 2.2.1.1 General-Purpose Registers . 10 2.2.1.2 EFLAGS Register . 11 2.2.1.3 Segment Registers . 12 2.2.1.4 Instruction Pointer . 12 2.2.1.5 Control Registers and Other System Registers . 13 2.2.2 Stack . 13 2.2.3 Privileges . 13 2.2.4 Modes of Operation . 14 2.2.5 Memory Protection Overview . 15 2.2.6 Assembly Language . 16 2.3 Memory Management . 17 2.3.1 Address and Operand Sizes . 17 2.3.2 Segmentation . 18 2.3.2.1 Real-Address Mode Segmentation . 18 2.3.2.2 Protected Mode Segmentation . 19 v vi CONTENTS 2.3.2.2.1 Segment Descriptor . 19 2.3.2.2.2 Segmenting the Linear Address Space . 21 2.3.2.2.3 Global Descriptor Table . 23 2.3.2.2.4 Segment Selectors . 23 2.3.2.2.5 System Descriptors . 24 2.3.3 Paging . 25 2.3.3.1 Translation Mechanism . 25 2.3.3.2 Memory Isolation . 27 2.3.3.3 Identity Paging . 27 2.3.3.4 Translation Lookaside Buffers . 28 2.4 Calls, Interrupts and Exceptions . 28 2.4.1 Near Calls . 29 2.4.2 Far Calls . 30 2.4.2.1 A Syntactic Digression . 30 2.4.2.2 Intra-Privilege Calls . 31 2.4.2.3 Inter-Privilege Calls . 31 2.4.3 Interrupts and Exceptions . 32 2.5 Tasks . 34 2.5.1 Task-State Segment . 34 2.5.2 Task Register . 35 2.5.3 Using Tasks . 35 2.6 System Calls . 36 2.6.1 Triggering a System Call . 36 2.6.2 Passing Arguments . 37 2.7 Boot . 37 I Semantics of Mixed C and x86 Assembly 39 3 Introduction 41 4 A Minimal C-like Language 43 4.1 Syntax . 43 4.2 Labels . 45 4.3 Semantics . 47 4.3.1 Memory Model . 48 4.3.2 Transition Systems . 49 4.3.3 Semantics of Lvalues and Expressions . 49 4.3.4 Semantics of Statements . 51 4.3.4.1 Transition Relation . 52 4.3.4.1.1 Blocks . 52 4.3.4.1.2 Conditional Branching . 53 4.3.4.1.3 Loop Statements . 53 4.3.4.1.4 Assignments . 54 CONTENTS vii 4.3.4.1.5 Declarations . 54 4.3.4.1.6 Return Statements . 55 4.3.4.1.7 Function Calls . 56 4.3.4.2 Initial States . 57 4.4 Comparison with Real C and Thoughts . 58 4.4.1 The Place of Undefined, Unspecified and Implementation-Defined Behaviors . 58 4.4.2 Desugaring C . 59 4.4.3 A Computability Digression . 60 4.4.4 Non-determinism and Memory Usage . 61 5 The Assembly Language 63 5.1 Structure of x86 Assembly Language . 64 5.2 Memory Model for Assembly . 65 5.3 The Reduced Instruction Set . 68 5.4 A Very Concrete Semantics . 69 5.5 A More Symbolic Semantics . 77 5.6 Comparison of Semantics . 80 6 Non-semantic Aspects of Mixed C and Assembly 81 6.1 Syntax of Assembly Blocks . 81 6.2 Sharing Operands . 82 6.2.1 Global Variables .