Projet de portage du mécanisme d'isolation des engagements sur Linux

L'auteur de la bibliothèque standard C Cosmopolitan et de la plateforme Redbean a annoncé la mise en œuvre du mécanisme d'isolation promise() pour Linux. Pledge a été initialement développé par le projet OpenBSD et vous permet d'interdire de manière sélective aux applications d'accéder aux appels système inutilisés (une sorte de liste blanche d'appels système est formée pour l'application, et les autres appels sont interdits). Contrairement aux mécanismes de restriction des appels système disponibles sous Linux, tels que seccomp, le mécanisme de gage a été conçu à l'origine pour être aussi simple que possible.

L'échec de l'initiative visant à isoler les applications dans l'environnement de base OpenBSD à l'aide du mécanisme systrace a montré que l'isolation au niveau des appels système individuels était trop complexe et prenait beaucoup de temps. Comme alternative, un gage a été proposé, qui permettait de créer des règles d'isolement sans entrer dans les détails et sans manipuler des classes d'accès toutes faites. Par exemple, les classes proposées sont stdio (entrée/sortie), rpath (fichiers en lecture seule), wpath (écrire des fichiers), cpath (créer des fichiers), tmppath (travailler avec des fichiers temporaires), inet (sockets réseau), unix ( unix sockets), dns (résolution DNS), getpw (accès en lecture à la base de données utilisateur), ioctl (appel ioctl), proc (gestion des processus), exec (lancement du processus) et id (gestion des droits d'accès).

Les règles d'utilisation des appels système sont spécifiées sous forme d'annotations, notamment une liste des classes d'appels système autorisées et un tableau de chemins de fichiers auxquels l'accès est autorisé. Après avoir construit et lancé l'application modifiée, le noyau prend en charge le travail de surveillance du respect des règles spécifiées.

Une implémentation distincte de Gage est en cours de développement pour FreeBSD, qui se distingue par la capacité d'isoler les applications sans apporter de modifications à leur code, tandis que dans OpenBSD, l'appel de gage vise une intégration étroite avec l'environnement de base et l'ajout d'annotations au code de chacun. application.

Les développeurs du port Gage pour Linux ont pris l'exemple de FreeBSD et, au lieu d'apporter des modifications au code, ont préparé un utilitaire complémentaire Gage.com qui vous permet d'appliquer des restrictions sans modifier le code de l'application. Par exemple, pour exécuter l'utilitaire curl avec un accès uniquement aux classes d'appels système stdio, rpath, inet et threadstdio, exécutez simplement « ./pledge.com -p 'stdio rpath inet thread' curl http://example.com ».

L'utilitaire de promesse fonctionne sur toutes les distributions Linux commençant par RHEL6 et ne nécessite pas d'accès root. De plus, sur la base de la bibliothèque cosmopolite, une API est fournie pour gérer les restrictions dans le code du programme en langage C, ce qui permet, entre autres, de créer des enclaves pour restreindre sélectivement l'accès à certaines fonctions de l'application.

L'implémentation ne nécessite aucune modification du noyau : les restrictions de promesse sont traduites en règles SECCOMP BPF et traitées à l'aide du mécanisme natif d'isolation des appels système Linux. Par exemple, l'appel promise("stdio rpath", 0) sera converti en un filtre BPF static const struct sock_filter kFilter[] = { /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall, 0, 14 - 1 ), / * L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])), /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 4 - 3, 0), /* L3* / BPF_JUMP( BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 13 - 4), /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])), /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800), /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 8 - 7, 0), /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 13 - 8) , /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 12 - 10, 0), /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 12 - 11, 0), /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 17, 0, 13 - 11), /*L12*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L14*/ /* filtre suivant */ };

Source: opennet.ru

Ajouter un commentaire