Secure Compilation for Memory Protection Alexandre Dang
Total Page:16
File Type:pdf, Size:1020Kb
Secure compilation for memory protection Alexandre Dang To cite this version: Alexandre Dang. Secure compilation for memory protection. Cryptography and Security [cs.CR]. Université Rennes 1, 2019. English. NNT : 2019REN1S111. tel-02972693 HAL Id: tel-02972693 https://tel.archives-ouvertes.fr/tel-02972693 Submitted on 20 Oct 2020 HAL is a multi-disciplinary open access L’archive ouverte pluridisciplinaire HAL, est archive for the deposit and dissemination of sci- destinée au dépôt et à la diffusion de documents entific research documents, whether they are pub- scientifiques de niveau recherche, publiés ou non, lished or not. The documents may come from émanant des établissements d’enseignement et de teaching and research institutions in France or recherche français ou étrangers, des laboratoires abroad, or from public or private research centers. publics ou privés. THÈSE DE DOCTORAT DE L’UNIVERSITÉ DE RENNES 1 COMUE UNIVERSITÉ BRETAGNE LOIRE ÉCOLE DOCTORALE N° 601 Mathématiques et Sciences et Technologies de l’Information et de la Communication Spécialité : (voir liste des spécialités) Par Alexandre DANG Compilation Sécurisée pour la Protection de la Mémoire Thèse présentée et soutenue à Rennes, le 10 Décembre 2020 Unité de recherche : Celtique Thèse N° : Rapporteurs avant soutenance : Tamara Rezk Inria Sofia Antipolis Alejandro Russo Chalmers University of Technology Composition du Jury : Attention, en cas d’absence d’un des membres du Jury le jour de la soutenance, la composition du Jury ne comprend que les membres présents Président : Prénom Nom Fonction et établissement d’exercice (à préciser après la soutenance) Examinateurs : Frédéric Besson Inria Rennes Tamara Rezk Inria Sofia Antipolis Alejandro Russo Chalmers University of Technology Heydemann Karine Université Pierre et Marie Curie Viet Triem Tong Valérie CentraleSupélec Dir. de thèse : Thomas JENSEN Inria Rennes COMPILATION POUR LA PROTECTION DE LA MÉMOIRE Nos vies sont de plus en plus dépendantes des systèmes informatiques et cette tendance devrait s’accentuer dans les années à venir. Que ce soit dans la santé, les transports ou l’économie, ces différents domaines ne sont plus capables de fonctionner correctement sans l’utilisation de ces systèmes. De ce fait, l’intérêt porté sur la sécu- rité informatique a également pris de l’importance, en conséquence des retombées désastreuses que peuvent provoquer les cyber attaques. Cette thèse a pour but d’améliorer la sécurité des systèmes informatiques en s’intéressant à la compilation sécurisée des programmes. La compilation est le processus de tra- duction d’un programme source écrit par des humains vers du code machine lisible par nos processeurs. Il existe deux manière de faire de la compilation sécurisée: par application ou par préservation d’une politique de sécurité. Appliquer une politique de sécurité à un programme durant la compilation consiste à prendre n’importe quel programme en entrée et de toujours produire un programme sécurisé en sortie. Un tel exemple est le compilateur gcc patché avec StackGuard [29] qui produit des exé- cutables résistants aux attaques de type buffer overflow [70]. Dans ce cas précis, la politique de sécurité appliquée est choisie par le compilateur ce qui peut poser prob- lème lorsqu’elle diffère du choix de l’utilisateur. Un compilateur préservant la sécurité des programmes suit un objectif différent, celui-ci s’assure que le programme compilé soit au moins aussi sécurisé que le programme source. Par exemple, Jasmin [3] est un compilateur dédié aux implémentations cryptographiques et garantit qu’un programme compilé respecte les mêmes propriétés de sécurité que sa version source. Le choix de compilateur sécurisé dépend du degré de confiance accordé au programme source qui va être compilé. Dans le cas où le programme source est d’origine inconnue ou malveillante, on utilisera l’application de sécurité pour être sûr d’obtenir un programme sécurisé en sortie. Au contraire, lorsque la politique de sécurité est mise en place par les développeurs dans le code source d’un programme, on utilisera plutôt à un com- pilateur qui s’assurera que la sécurité du programme source soit préservée jusqu’au 3 programme exécutable. Les deux types de compilation sécurisée présentés seront abordés dans cette thèse. Tout d’abord nous avons développé le compilateur COMPCERTSFI qui applique les techniques de Software Fault Isolation (SFI) sur les programmes transformés. La deuxième partie de la thèse se concentre sur la préservation de propriétés de sécurité durant la compilation. Nous avons défini une propriété appelée Information Flow Pre- serving qui garantit qu’une transformation produise des programmes aussi sécurisés que que leurs version source. COMPCERTSFI Software Fault Isolation (SFI) est une technique d’isolation qui essaye de maximiser les temps d’exécution. Les principes fondamentaux de SFI ont été établis par Wahbe et al. [114] et les travaux qui suivent tels que NaCl [117] ou Pittsfield [73] sont tous basés sur ces principes. Nous commençons par présenter les fondamentaux de SFI pour ensuite nous pencher sur notre compilateur COMPCERTSFI. Software Fault Isolation (SFI) Différentes méthode d’isolation existent comme les machines virtuelles ou la mémoire virtuelle entre processus. SFI est la technique qui réduit au maximum les interactions entre un programme hôte et différents modules qui peuvent être malveillants. Pour cela, dans SFI, le programme hôte accueille dans sa propre mémoire, les différents modules avec lesquels il veut interagir. Pour éviter que ces modules corrompent la mémoire du programme hôte, ils sont placés dans des zones mémoires attitrées, appelées sandbox. La politique de sécurité de SFI décrite par Wahbe et al. est la suivante: — Sûreté de la mémoire: un module ne peut ni lire, ni écrire ni sauter hors de sa sandbox. — Communication sécurisée: toute communication entre l’hôte et ses modules passent à travers une interface qui vérifie leur légitimité. — Vérification du code: tout code exécuté par un module a été au préalable con- trôlé de manière à ce qu’il satisfasse les deux règles précédentes SFI est composée de deux éléments majeurs: un générateur et un vérifieur. Le généra- teur est intégré durant la compilation et transforme le code d’un module de manière à 4 ce qu’il satisfasse les règles de sûreté de la mémoire et de communication sécurisée. Ensuite, avant de charger le code d’un module en mémoire, il sera contrôlé par le vérifieur qui s’assure que le code respecte la politique de sécurité de SFI. De nombreux travaux ont été effectué sur SFI tels que MiSFIt [107], Pittsfield [73] ou NaCl [117, 98, 6] qui a été utilisé dans le navigateur Google Chrome. Le principal but de ces travaux a été de diminuer au maximum, les ralentissements introduits par les transformations de programme de SFI. COMPCERTSFI COMPCERTSFI est un compilateur basé sur COMPCERT [66] qui pro- duit des programmes respectant la politique de sécurité de SFI. COMPCERT est un compilateur certifié, pour le langage C, prouvé avec l’assistant de preuve Coq [112], de respecter un théorème de préservation des programmes compilés. Grâce à ce théorème de préservation, COMPCERTSFI peut retirer le vérifieur SFI des outils de SFI. En effet, COMPCERTSFI possède seulement un générateur de code pour SFI mais pas de vérifieur. Cette approche a d’abord été théorisé par PSFI [60] et COMPCERTSFI en est une implémentation compétitive et complète. L’idée est d’utiliser un générateur SFI assez tôt dans la chaîne de compilation, puis de profiter du théorème de préser- vation de COMPCERT pour préserver la sécurité de SFI dans le binaire produit. Les théorèmes prouvés sur le générateur SFI de COMPCERTSFI sont les suivants: — Sécurité: le code produit par le générateur ne peut accéder à de la mémoire situées en dehors de sa sandbox et toute interaction hôte-module est identifiée et contrôlée par une bibliothèque de confiance. — Sûreté: le code produit ne contient pas de comportements indéfinis Le théorème de sécurité correspond aux règles de sûreté de la mémoire et de com- munication sécurisée des principes de SFI et garantissent l’isolation des modules. Le théorème de sûreté est nécessaire pour pouvoir appliquer le théorème de préservation de COMPCERT qui cite: si un programme p ne contient pas de comportements indéfinis alors le programme compilé p′ a le même comportement que p. Grâce à ce théorème de préservation, nous avons la garantie que les transformations faites auparavant par le générateur SFI sont conservées durant la compilation et que le programme compilé est bien isolé dans sa sandbox. Ne pas posséder de vérifieur donne plusieurs avantages. Tout d’abord, puisque les transformations SFI se font à haut niveau, COMPCERTSFI supporte naturellement 5 toutes les architectures supportés par COMPCERT. Avec l’approche traditionnelle de SFI, nous sommes obligés de développer un générateur et un vérifieur pour chaque architecture. Un autre avantage est que les transformations SFI se font à haut niveau ce qui permet aux constructions SFI d’être optimisés par le compilateur. En effet, dans l’approche classique le vérifieur doit être capable de contrôler que du code respecte les principes de SFI et doit être donc facilement vérifiable. De ce fait, les transformations SFI ne sont pas optimisés afin d’être visible par le vérifieur SFI. Nous avons effectué des mesures des performances de COMPCERTSFI et les avons comparés avec NaCl. En moyenne, notre compilateur a des performances similaires à NaCl et nous avons observé que les différences résident principalement dans les performances du compilateur COMPCERT pour les temps d’exécution. En effet, COMP- CERT est plus lent que gcc ou Clang, utilisés par NaCl, et nos expériences montrent que l’impact de nos transformations SFI est modeste. Plusieurs pistes sont possi- bles pour améliorer COMPCERTSFI. La première est de tout simplement améliorer les performance de COMPCERT en utilisant des variantes plus rapides telle que COM- PCERTSSA [10] qui possède des optimisations supplémentaires. Une autre idée est de créer des optimisations spécifiques à SFI pour diminuer encore plus le ralentisse- ment provoqué par les constructions SFI rajoutées dans le code.