Récemment, l'auteur de la bibliothèque standard Cosmopolitan C et de la plateforme Redbean a annoncé l'implémentation du mécanisme d'isolation pledge() pour Linux.
Développé initialement par le projet OpenBSD , pledge permet d'interdire sélectivement aux applications d' accéder aux appels système inutilisés (en créant une liste blanche d'appels système pour l'application et en interdisant les autres). Contrairement aux mécanismes de contrôle d'accès aux appels système disponibles sous Linux, tels que seccomp, pledge a été conçu dès le départ pour être aussi convivial que possible.
L'initiative ratée d'isoler les applications dans l'environnement de base OpenBSD à l'aide du mécanisme systrace a démontré que l'isolation au niveau des appels système individuels est trop compliquée et prend du temps.
Une autre solution proposée était l’engagement, qui permettait de créer des règles d’isolation sans entrer dans les détails ni manipuler les classes d’accès préparées.
Par exemple, les classes proposées sont stdio (entrée/sortie), rpath (fichiers en lecture seule), wpath (fichiers en écriture), cpath (création de fichiers), tmppath (travail avec des fichiers temporaires), inet (réseau de sockets), unix (sockets unix ), dns (résolution DNS), getpw (accès en lecture à la base de données utilisateur), ioctl (appel ioctl), proc (contrôle de processus), exec (processus de démarrage) et id (contrôle des autorisations).
Les règles d'utilisation des appels système sont spécifiées sous forme d'annotations comprenant une liste des classes d'appels système autorisées et un tableau des chemins de fichiers accessibles. Après la compilation et l'exécution de l'application modifiée, le noyau se charge de vérifier la conformité aux règles spécifiées.
Séparément, l'implémentation de l'engagement pour FreeBSD est en cours de développement, qui se distingue par la capacité d'isoler les applications sans apporter de modifications à leur code, tandis que dans OpenBSD, l'appel d'engagement vise une intégration étroite avec l'environnement de base et l'ajout d'annotations au code de chacun.
Pledge est comme le fruit défendu que nous convoitons tous lorsque le patron dit que nous devrions utiliser des choses comme Linux. Pourquoi est-ce important? C'est parce que le pledge() rend la sécurité compréhensible. Linux n'a jamais vraiment eu une couche de sécurité que les simples mortels peuvent comprendre.
Les développeurs du portage Linux de Pledge ont suivi l'exemple de FreeBSD et, au lieu de modifier le code, ont préparé un utilitaire supplémentaire sur pledge.com permettant d'appliquer des restrictions sans altérer le code de votre application. Par exemple, pour exécuter l'utilitaire curl en n'ayant accès qu'aux classes d'appels système stdio, rpath, inet et threadstdio, il suffit d'exécuter `./pledge.com -p 'stdio rpath inet thread' curl http://example.com`.
Cet utilitaire fonctionne sur toutes les distributions Linux à partir de RHEL6 et ne nécessite pas d'accès root. De plus, grâce à la bibliothèque Cosmopolitan, une API est fournie pour la gestion des restrictions dans le code C, permettant notamment la création d'enclaves afin de restreindre sélectivement l'accès à certaines fonctions applicatives.
Il y a eu quelques développeurs dans le passé qui ont essayé cela. Je ne citerai pas de noms, car la plupart de ces projets n'ont jamais été achevés. En ce qui concerne SECOMP, les didacticiels en ligne expliquent uniquement comment ajouter des appels système à la liste blanche, de sorte que la plupart des gens perdent tout intérêt avant de comprendre comment filtrer les arguments. Les projets qui ont avancé ont également eu des oublis comme autoriser la modification des bits setuid/setgid/sticky. Par conséquent, aucune des alternatives actuelles ne devrait être utilisée. Je pense que cet effort nous rapproche beaucoup plus que jamais de l'engagement().
L'implémentation ne nécessite aucune modification du noyau : les contraintes d'utilitaire sont traduites en règles SECCOMP BPF et traitées à l'aide du mécanisme d'isolation des appels système natif de Linux. Par exemple, appeler promise("stdio rpath", 0) se convertira en un filtre BPF
Enfin, si vous souhaitez en savoir plus, vous trouverez les détails en suivant ce lien.