• Aucun résultat trouvé

Structurations pour un syst`eme s´ecuris´e

2.2 S´ ecurit´ e

2.2.3 Structurations pour un syst`eme s´ecuris´e

S’il y a consensus sur les principes `a respecter pour une conception s´ecuris´ee, les m´ethodes de structuration de tels syst`emes divergent. Rushby ´ecrit ainsi [Rus84] que le Orange Book16

n’est (intentionellement) pas un manuel d´ecrivant comment concevoir des syst`emes sˆurs. Nous d´ecrivons dans cette section les principales approches de structuration.

2.2.3.1 Syst`emes d’exploitation g´en´eralistes

Historique des syst`emes industriels La multiprogrammation apparu rapide- ment en raison du coˆut des premiers ordinateurs, qui furent ainsi utilis´es par de nombreux utilisateurs simultan´ement. Cela for¸ca les concepteurs de syst`emes d’ex- ploitation `a rendre leur syst`eme fortement s´ecuris´e. Un exemple pro´eminent de tel syst`eme est Multics [CV65].

Sur la g´en´eration suivante de « mini-ordinateurs », aux capacit´es plus restreintes, se sont d´evelopp´es des syst`emes d’exploitations simplifi´es (et avec des m´ecanismes de protection plus basiques), dont l’arch´etype est UNIX [RT74, Tho78]. Enfin, les micro-ordinateurs apparurent, qui ´etaient destin´es `a un usage personnel, et des syst`emes comme DOS ou les premi`eres versions de Windows n’avaient quasiment aucune notion de s´ecurit´e [Tan01]. La situation s’est l´eg`erement am´elior´ee depuis, notamment `a cause des menaces li´ees `a la connexion de ces syst`emes `a Internet, mais ces syst`emes sont r´eguli`erement sujets `a des vuln´erabilit´es aux cons´equences graves. Comme indiqu´e pr´ecedemment, pour qu’un syst`eme soit s´ecuris´e il faut qu’il soit con¸cu pour la s´ecurit´e depuis le d´epart.

16

le document du d´epartement de la d´efense am´ericain d´ecrivant la certification des syst`emes s´ecuris´es ;

2.2.3. Structurations pour un syst`eme s´ecuris´e

Noyaux monolithiques La mani`ere classique pour structurer un syst`eme d’ex- ploitation comme UNIX est le noyau monolithique : toutes les fonctions r´egissant la protection, la communication, et le partage des ressources se trouvent dans le noyau. Le noyau peut ainsi devenir assez gros (le noyau Linux fait ainsi plus de 6 millions de lignes de code [BC05]), et comme le noyau est privil´egi´e, le moindre bug peut impacter l’ensemble du syst`eme.

Micronoyaux Pour obtenir un syst`eme plus fiable, on a sorti du noyau certaines parties, comme la gestion du swapping ou des syst`emes de fichier, pour les mettre dans des tˆaches privil´egi´ees (appel´ees serveurs). Le noyau plus petit est ainsi appel´e micronoyau. Le syst`eme est plus fiable, car le noyau est plus petit, et que les diff´erents composants peuvent d´efaillir sans impacter les autres ; et plus modulaire, car les composants peuvent ˆetre facilement remplac´es.

Les premiers micronoyaux, comme Mach [ABG+

86] ou Chorus [RAA+

91], ressem- blaient `a des noyaux UNIX dont quelques composants ´etaient sortis. Les performances de ces syst`emes ´etaient mauvaises, ce qui montre qu’il ne faut pas les structurer comme un noyau monolithique. Les performances se sont grandement am´elior´ees dans des syst`emes plus modernes, dont le design ´etait refait depuis le d´ebut, notamment par les travaux de Ford et Liedtke [FL94, Lie93, Lie95a, HHL+97].

Ces noyaux restent cependant relativement gros (e.g. 8700 lignes de code pour seL4 [KEH+

09]), notamment en comparaison avec les separation kernels (§˜labelsec :separation-kernel-dss-mils)17

, ce qui les rend relativement complexes `a certifier. De plus, les tˆaches de confiance hors du noyau sont ´egalement relative- ment grosses, donc sujettes `a bugs, qui impactent tous les programmes qui d´ependent de cette tˆache. Une des raisons pour cela est la pr´esence d’abstraction dans le noyau et les tˆaches de confiance, i.e. le noyau et les tˆaches de confiance pr´esentent aux applications une interface de haut niveau relativement ind´ependante du mat´eriel sous-jacent. De plus, il y a souvent des probl`emes li´es `a la gestion des ressources et aux d´enis de service (e.g. [WB07], § 2.3).

Ainsi, le syst`eme PikeOS [KW07] a simplifi´e certains aspects de L4 pour arriver `a faire certifier le noyau. Notons cependant que des efforts sont en cours pour obtenir la preuve formelle de tels micronoyaux (e.g. seL4 [KEH+

09], Coyotos [SDD+

04]). Enfin, notons que les micronoyaux r´ecents se rapprochent des syst`emes `a capacit´es afin d’obtenir un mod`ele formel de s´ecurit´e, notamment sous l’impulsion des travaux de Shapiro dans EROS [Sha99, SSF99].

Virtualisation Les syst`emes traditionnels n’´etant pas s´ecuris´es, une solution pour assurer l’isolation est la virtualisation. Il s’agit d’encapsuler des syst`emes d’exploitation entiers dans une machine virtuelle. On rajoute ainsi une couche, le moniteur de machine virtuelle (VMM), qui permet de faire fonctionner plusieurs syst`emes simultan´ement.

Dans cette approche, la protection n’est assur´ee qu’`a gros grain : mˆeme si le VMM est tr`es s´ecuris´e, la protection n’est pas assur´ee pour les diff´erentes tˆaches

17

notons cependant que ces noyaux permettent beaucoup plus de fonctionnalit´es, comme la cr´eation dynamique de tˆaches

dans une mˆeme machine virtuelle. De plus, les VMMs ont ´egalement tendance `a grossir , et peuvent ˆetre eux mˆeme victimes de failles de s´ecurit´e [Orm07]. Enfin, le dernier d´esavantage de cette approche est l’overhead associ´e `a l’ajout d’une nouvelle couche, mˆeme si des syst`emes comme Xen [BDF+

03] ont fortement r´eduit ce coˆut, notamment par l’emploi de la paravirtualisation (i.e. la modification du code du syst`eme d’exploitation `a virtualiser), et l’int´egration par le mat´eriel de m´ecanismes facilitant la virtualisation.

La virtualisation est donc surtout int´eressante pour assurer la compatibilit´e avec des applications d´evelopp´ees pour d’autres syst`emes, mais pas dans l’optique de d´evelopper un nouveau syst`eme s´ecuris´e.

Exonoyaux Certains syst`emes d’exploitations proposent de retirer toute abstrac- tion du noyau, et de placer ces abstractions dans des librairies (appel´ees libOS) : ce sont les exonoyaux . Ils ressemblent `a des moniteurs de machines virtuelles par- avirtualis´ees, mais ex´ecutent des tˆaches directement au lieu d’ex´ecuter des syst`emes d’exploitation entiers. L’interface est proche, mais g´en´eralement diff´erente de celle du mat´eriel nu, ce qui la simplifie.

Entre autre syst`emes bas´es sur cette approche, on trouve Aegis et Xok [EKJO95, KEG+97], Nemesis [Ros95], ou Denali [WSG02]. Ces syst`emes ont montr´es qu’ils

pouvaient atteindre, voire surpasser les performances des syst`emes traditionnels, et ´etaient plus flexibles.

En supprimant les abstractions et en les mettant dans des librairies, ces syst`emes r´eduisent de mani`ere drastique la taille du noyau, et ne sont pas plus difficiles `a concevoir et impl´ementer que des syst`emes monolithiques traditionnels. Notons cependant que le partage des ressources est toujours de la responsabilit´e du noyau, alors que les micronoyaux l’avaient export´e.

Protection logicielle La mani`ere traditionnelle d’impl´ementer la s´eparation des domaines est par la protection mat´erielle, i.e. l’utilisation d’un m´ecanisme mat´eriel qui v´erifie que chaque acc`es m´emoire fait par le processeur est autoris´e. Ce m´ecanisme est appell´e MMU ou MPU , la diff´erence ´etant que la MMU impl´emente ´egalement une translation d’adresses.

Certains programmes sont ´ecrits dans des langages « sˆurs », qui ne peuvent acc´eder qu’`a des adresses autoris´ees par construction. Lorsqu’on ex´ecute un programme ´ecrit dans un langage sˆur, la protection mat´erielle est ainsi superflue. Certains syst`emes proposent alors de la supprimer enti`erement [HAF+

07].

Les approches pour s’assurer qu’un code est sˆur sont diverses ; il y a l’utilisation d’un langage « type-safe » [BSP+

95], la compilation en bytecode, ou le scan de code [Rip03]. Ces approches souffrent de d´efauts vari´es :

• mˆeme si un code a ´et´e ´ecrit dans un langage type-safe, il est difficile de montrer qu’un binaire a ´et´e produit depuis un tel langage. Il faut pour cela que le compilateur soit inclut dans le noyau, ou que l’ensemble des binaires `a ex´ecuter soit connu avant le d´ebut de l’ex´ecution. L’approche consistant `a signer des binaires [LMR00] n’empˆeche pas ces binaires de mal fonctionner ;

2.2.3. Structurations pour un syst`eme s´ecuris´e • l’utilisation de bytecode permet de simplifier le « compilateur dans le noyau »,

mais mˆeme ainsi celui-ci reste complexe ;

• mˆeme pour un « simple » scanneur de code, il est difficile de s’assurer qu’on a v´erifi´e toutes les attaques possibles. En particulier, il est difficile d’empˆecher du code de cr´eer et d’ex´ecuter un autre code malicieux apr`es le scan (sans restriction sur les processus [HAF+

07]).

Enfin, toutes ces approches souffrent de probl`emes communs :

• l’utilisation de code sˆur cause un overhead `a l’ex´ecution, `a cause des v´erifications des indices de tableaux, etc. De plus, cela cause ´egalement un overhead `a la cr´eation/initialisation du programme, pour v´erifier que le code est bien sˆur ; • le fait que la protection logicielle demande de faire confiance `a un compilateur

complexe ne permet pas l’´evaluation de ces syst`emes aux plus hauts niveaux de s´ecurit´e [Rus84] ;

• mˆeme si la protection logicielle se faisait en z´ero-d´efaut, cela ne rend pas le syst`eme sˆur pour autant[Den76]. Ainsi un changement de bit intempestif (bitflip) pendant le calcul d’adresse par le processeur serait d´etect´e avec une grande chance par un syst`eme `a protection mat´erielle, tandis que cela pourrait passer inaper¸cu dans un syst`eme `a protection logicielle ;

• enfin, la protection logicielle ne permet pas en g´en´eral l’ex´ecution de tout code qui ne soit pas ´ecrit dans un langage sˆur (sauf par utilisation de certains scanneurs de code, qui affectent beaucoup les performances [Rip03, § 4.2.3.2]). Ils ne peuvent donc ˆetre utilis´e pour ex´ecuter du code existant.

Finalement, le coˆut de changement d’espace d’adressage n’est pas si important sur des processeurs qui le supportent efficacement. Malheureusement, la domination des syst`emes monolithiques (Windows et les variantes d’UNIX) sur le parc de machines actuels n’incite pas les fabriquants de processeurs x86 `a optimiser ce coˆut.

Conclusion La domination des noyaux monolithiques dans les syst`emes non- acad´emiques d´emontre l’effort de conception n´ecessaire pour arriver `a ´ecrire un syst`eme s´ecuris´e. Les syst`emes modernes (micronoyaux, exonoyaux, VMMs) se concentrent essentiellement sur les aspects pratiques de l’impl´ementation de syst`emes plus fiables, et ne s’int´eressent traditionellement pas `a une assurance plus formelle de la s´ecurit´e (bien que cela soit en train de changer avec la convergence des micronoyaux avec les syst`emes `a capacit´es, comme dans EROS et seL4 [SSF99, KEH+

09]). On y trouve n´eanmoins quantit´e de m´ecanismes int´eressants pour la performance, la flexibilit´e et l’extensibilit´e, dont certains seront d´ecris dans les sections suivantes. 2.2.3.2 Security kernels

L’approche historique pour construire des syst`emes s´ecuris´es est le « security kernel » [Gas88] : l’id´ee est de minimiser le noyau pour qu’il incorpore toutes les fonctions

de s´ecurit´e, et uniquement celles-l`a. Tout ce qui n’est pas n´ecessaire pour assurer la s´ecurit´e doit alors sortir du noyau18

.

Les fonctions de s´ecurit´e assur´ees par le security kernel sont de deux types [Rus81] : la s´eparation en diff´erents domaines de protection, et l’application de la politique de s´ecurit´e. En pratique, quasiment tous les syst`emes bas´es sur cette approche ont impl´ement´e la politique de s´ecurit´e multi-niveaux [Gas88, p. 140].

Le probl`eme de cette approche est qu’une seule politique de s´ecurit´e peut ˆetre prise en compte dans le syst`eme. Or un syst`eme a en g´en´eral besoin de « tˆaches de confiance », qui ne peuvent pas rentrer dans la politique de s´ecurit´e [Rus81] (surtout MLS, tr`es restrictive). Des exemples sont les tˆaches qui font un backup du syst`eme, ou des filtres permettant de d´eclassifier des informations. Ceci contribue `a rendre complexe le noyau, ces tˆaches de confiances et leurs interactions, ces tˆaches ´etant en dehors de toute politique de s´ecurit´e. Ceci augmente la probabilit´e de failles de s´ecurit´e.

2.2.3.3 Separation kernels, DSS, et MILS

Separation kernel et approche distribu´ee de la s´ecurit´e En comparant les security kernels `a d’autres architectures pour la s´ecurit´e, Rushby a not´e que cette approche n’´etait pas ad´equate. Cela l’a conduit `a d´efinir une approche bas´ee sur l’´emulation de syst`emes distribu´es [Rus81]. Dans cette approche, un separation kernel est utilis´e dans le seul but d’assurer l’isolation entre les diff´erents domaines, et de contrˆoler les communications entre ces domaines (cette politique de s´ecurit´e du noyau est appell´ee « channel control »[BDRS08]). Toutes les autres fonctions de s´ecurit´e sont assur´ees par des tˆaches de confiance.

L’int´erˆet de l’approche est de s´eparer les politiques de s´ecurit´e en modules ind´ependants, qui ne font qu’un travail simple. La composition et les relations entre les modules est formalis´ee [BDRS08] par la pr´esence (ou l’absence) de liens v´erifi´es par le separation kernel ; on peut repr´esenter le syst`eme par un diagramme « boites - flˆeches », o`u les boites repr´esentent des domaines et les fl`eches les liens de communication. La politique de s´ecurit´e est assur´ee en v´erifiant que l’ensemble des liens de communication entre deux domaines passe par des domaines de confiance, qui filtrent la communication chacun selon une politique locale simple sp´ecifique. Rushby indique que la diff´erence formelle entre cette approche et celle des security kernels est la non-transitivit´e de l’interf´erence [Rus92] : si a ne peut communiquer avec c qu’en passant par b, cela est bien diff´erent de si a peut directement communiquer avec c si b agit comme un filtre de confiance.

Cette architecture a ´et´e d´eclin´ee de plusieurs mani`eres. Dans [Rus84], Rushby propose un syst`eme `a trois niveaux, constitu´e d’un separation kernel, de diff´erents ressources managers, et d’un dernier niveau applicatif. Les syst`emes `a micronoyaux reposeront plus tard sur une architecture de ce type.

Le syst`eme DSS [RR83] a d´evelopp´e l’approche de Rushby et montr´e comment structurer un syst`eme s´ecuris´e distribu´e. En particulier, c’est DSS qui a montr´e

18

ceci peut se faire en r´e´ecrivant un syst`eme, ou en rajoutant un « VMM de s´ecurit´e » en sous-couche [Gas88, § 10.7]

2.2.3. Structurations pour un syst`eme s´ecuris´e

comment utiliser les « trusted mediators » pour assurer une politique de s´ecurit´e multiniveau (MLS ).

MILS MILS [AFHOT06] est une m´ethodologie d’´ecriture de syst`emes fond´ee sur cette approche distribu´ee de la s´ecurit´e. L’id´ee est de d´ecomposer un syst`eme r´ecursivement, afin de minimiser la taille des domaines de confiance (e.g. ceux qui g`erent les donn´ees de diff´erentes sources simultan´ement). Ces domaines deviennent facilement v´erifiables. Cette approche peut ˆetre ´etendue pour obtenir une certification compositionelle [BDRS08] : une « policy architecture » formelle permet de montrer que la composition des politiques de s´ecurit´e locales permet d’assurer la politique de s´ecurit´e globale du syst`eme. De plus, cette approche de structuration du syst`eme pour faciliter l’assurance de la s´ecurit´e est ind´ependante de la mani`ere dont les tˆaches sont plac´ees : elles peuvent ainsi ˆetre sur diff´erents ordinateurs ou sur le mˆeme sur lequel est ex´ecut´e un separation kernel. Cette approche semble tr`es prometteuse pour une certification composable, et permettrait mˆeme la r´eutilisation de composants certifi´es.

Notons que dans l’architecture MILS, le but n’est pas d’avoir differents niveaux de securit´e de diff´erentes sensibilit´es, mais de pouvoir traiter simultan´ement des informations s´epar´ees en plusieurs « classes » relativement ind´ependantes. Ces classes sont ´egalement appell´ee niveaux (ce qui prˆete `a confusion). MLS est donc un cas particulier de MILS.

Conclusion Les separation kernels et la structuration avec MILS sont des ap- proches de choix pour la r´ealisation de syst`eme hautement s´ecuris´es, et qui pourraient mˆeme permettent une approche compositionelle de la certification [BDRS08]. Le point cl´e est que la protection entre domaines est ind´ependante de la politique de s´ecurit´e ; cette derni`ere est r´ealis´ee seulement en param´etrant les liens entre domaines.

Cependant, il y a un point qui n’est pas pris en compte par cette approche, c’est la dynamicit´e. Mˆeme si, actuellement, les applications les plus critiques sont statiques, il est dommage de ne pas pouvoir faire profiter des syst`emes plus dynamiques d’une structuration s´ecuris´ee de ce type. Les syst`emes dynamiques sont g´en´eralement confin´es dans des compartiments (e.g. souvent un OS virtualis´e) qui ne sont pas s´ecuris´es. Les syst`emes suivants proposent des solutions `a ces probl`emes.

2.2.3.4 Les syst`emes `a capacit´es

Introduction On appelle syst`eme `a capacit´e un syst`eme dont la protection est principalement bas´ee sur l’utilisation de capacit´es. Ces syst`emes sont le plus souvent g´en´eraliste, mais leur conception est relativement diff´erente de celle des syst`emes traditionels.

Une capacit´e est une sorte de « cl´e virtuelle », dont la possession par une tˆache indique son autorisation `a utiliser une ressource. Bien que ce m´ecanisme soit commun dans beaucoup de syst`emes (les descripteurs de fichiers UNIX en sont un exemple), les syst`emes `a capacit´e, dont le contrˆole d’acc`es est fond´e uniquement sur les capacit´es, sont plus rares.

Bien qu’il existe plusieurs mod`eles pour les capacit´es, la majorit´e de ces syst`emes utilisent le mod`ele des capacit´es-objet [MYS03, MS03], que nous d´ecrivons par la suite. Basiquement, l’usage des capacit´es impl´emente la politique de « channel control » des separation kernels ; et permet donc de r´ealiser des syst`emes comme MILS. Mais c’est bien plus que cela, car les droits peuvent ˆetre pass´es pour ´evoluer dynamiquement, tout en permettant de pr´edire et restreindre cette ´evolution ; de nouvelles propri´et´es de s´ecurit´e peuvent ˆetre facilement construites ; le tout dans un mod`ele formalis´e et facile `a comprendre, car fortement reli´e `a la programmation orient´ee objet. Les capacit´es permettent donc la s´eparation entre protection et politique de s´ecurit´e [WCC+74] sur un syst`eme dynamique.

Historique Jusqu’au d´ebut des ann´ees 80, les syst`emes `a capacit´es ´etaient une conception de choix pour la r´ealisation de syst`emes s´ecuris´es (comme en t´emoigne la retrospective de Levy [Lev84]), ou sˆurs de fonctionnement [Den76]. Elles ont ´et´e par la suite plus ou moins abandonn´ees, mis `a part dans quelques rares syst`emes comme KeyKOS [Har85]19

, avant de retrouver un (relatif) regain d’int´erˆet depuis les travaux de Shapiro et Miller [SSF99, MYS03]. Il y a plusieurs raisons qui expliquent cette perte d’int´erˆet :

• les syst`emes `a capacit´es tournaient en majorit´e sur des syst`emes dont l’archi- tecture m´emoire ´etait compliqu´ee, ce qui rendait ces syst`emes lents [Sha99, p. 11] ;

• le mod`ele th´eorique ´etait caract´eris´e de mani`ere impropre, ce qui a engendr´e des r´esultats d’impossibilit´es tr`es n´egatifs [MYS03]. En particulier, il n’avait jamais ´et´e prouv´e que les syst`emes `a capacit´e pouvaient assurer le confinement, ´etape n´ecessaire pour obtenir une politique MLS [SSF99] (alors qu’il existait des syst`emes `a capacit´e qui impl´ementaient MLS [Key89]). Le probl`eme est que les preuves th´eoriques ne prenaient pas en compte l’existence de programmes de confiance [MS03].

On peut ainsi voir les syst`emes `a capacit´es comme une extension dynamique de l’architecture MILS.

R´esultats Parmis les r´esultats th´eoriques les plus int´eressants sur la conception de syst`emes `a capacit´es, on peut citer celui de Dennis et Van Horn [DH66] (qui a introduit le concept), le papier de Saltzer et Schroeder [SS74] (qui d´ecrit comment