Aperçu de l’IPC de Hubris
- Hubris utilise un noyau petit et indépendant de l’application, et la majeure partie du code (pilotes, logique applicative, pile réseau, etc.) existe dans des tâches isolées compilées séparément
- Ces tâches peuvent communiquer entre elles à l’aide d’un système de messagerie inter-tâches (IPC)
- L’IPC de Hubris se compose de 3 opérations fondamentales implémentées dans le noyau (RECV, SEND, REPLY)
- RECV : récupère le message entrant de plus haute priorité, ou bloque jusqu’à l’arrivée d’un message
- SEND : transmet un message et le contrôle à la tâche destinataire, puis suspend l’appelant. L’appelant passe en attente jusqu’à recevoir une réponse
- REPLY : remet une réponse à la tâche qui a précédemment utilisé SEND afin qu’elle puisse reprendre son exécution
Nouveaux modes de défaillance intéressants
- Comme l’IPC traverse les frontières entre tâches et que les tâches de Hubris sont des programmes compilés séparément, il faut être prudent lorsqu’on applique à l’IPC les mêmes hypothèses que celles faites par le compilateur pour les appels de fonction
- Dans Hubris, toute tâche jouant le rôle de serveur IPC doit gérer les erreurs potentielles suivantes :
- recevoir un message avec une interface et un code d’opération inadaptés
- recevoir, au lieu du type de message attendu, un ensemble d’octets impossible à interpréter, ou un message trop court ou trop long
- ne pas recevoir la mémoire nécessaire (par exemple de la mémoire accessible en écriture)
Dans un programme normal et correct, ces situations ne se produisent pas
- Dans un programme Hubris normal, les situations mentionnées ci-dessus ne se produisent pas
- Les tâches sont reliées entre elles par la configuration du système de build, ce qui rend les confusions difficiles
- Le client et le serveur utilisent du code Rust généré, ce qui permet de supposer que le système de types fonctionne au-delà des frontières entre tâches
Le noyau n’autorise aucun non-sens
- Sous Unix, violer les préconditions d’un appel système renvoie un code d’erreur à l’appelant, mais dans Hubris la tâche est immédiatement détruite
- Le noyau de Hubris transmet une erreur aux tâches qui enfreignent ses règles via le concept de faute synthétique (Synthetic Fault)
- Dans Hubris, lorsqu’une faute matérielle ou synthétique se produit, la tâche est immédiatement arrêtée et ne peut pas être récupérée
Le serveur non plus n’autorise aucun non-sens
- Grâce à REPLY_FAULT, le 13e appel système et le plus atypique, le serveur peut transmettre une erreur au client
- REPLY_FAULT ressemble à REPLY, mais au lieu de transmettre un message et de rendre la tâche exécutable, il transmet une erreur et interrompt la tâche
- REPLY_FAULT permet d’éviter de gérer inutilement les erreurs IPC. Les programmes normaux peuvent se comporter comme si les problèmes étaient impossibles, et les programmes anormaux n’ont même pas l’occasion de traiter l’erreur
- REPLY_FAULT offre une nouvelle façon de définir et d’implémenter des erreurs propres à l’application, comme les règles de contrôle d’accès
L’avis de GN⁺
- REPLY_FAULT est un mécanisme puissant qui permet à un serveur de déclencher un
panic! inter-processus côté client sans coopération du client. Cela fait de Hubris un système très hostile aux programmes malveillants
- L’inconvénient de REPLY_FAULT est qu’il rend le fuzzing très difficile. Une tâche de chaos engineering qui génère des IPC ou des appels système aléatoires est réinitialisée presque immédiatement dans la plupart des cas
- Cependant, comme les tâches Hubris normales ne génèrent pas dynamiquement de messages IPC, elles peuvent fonctionner sans même avoir conscience de l’existence de REPLY_FAULT
- REPLY_FAULT permet au serveur de provoquer arbitrairement des erreurs chez le client, mais son évaluation n’est pas encore totalement aboutie
- La gestion agressive des erreurs dans Hubris aide à détecter les fautes tôt dans le développement et, contrairement aux codes d’erreur, empêche de les ignorer
- Utiliser une méthode universelle de traitement des erreurs IPC peut entraîner une surcharge inutile même pour les programmes normaux. REPLY_FAULT semble être une solution élégante qui évite cela tout en réagissant strictement face aux programmes anormaux
1 commentaires
Avis Hacker News
En résumé, voici les points soulevés :
Des inquiétudes sont exprimées quant à la propagation en chaîne de
REPLY_FAULTet aux vulnérabilités qui pourraient en découlerREPLY_FAULTde C entraîne aussi la terminaison de ASENDforme une structure cyclique, il pourrait même arriver qu'un processus se termine lui-même involontairementREPLY_FAULTfournit un moyen de définir et d'implémenter des erreurs spécifiques à l'application, comme le contrôle d'accèsDans un système où une seule équipe écrit tout le code, éliminer les clients suspects peut accélérer l'itération
On peut voir Hubris comme un kernel qui permet aux serveurs d'effectuer des effets que les clients ne peuvent pas gérer
Hubris et Humility sont des technologies dans lesquelles on aimerait s'immerger profondément, mais c'est difficile faute de temps et à cause des obligations
Une RFC du 1er avril sur HTTP propose le code d'état HTTP 499, signifiant « vous devriez avoir honte »
En citant la maxime d'Einstein « aussi simple que possible, mais pas plus simple », il est souligné que la conception de Hubris enfreint la seconde partie
Humility est un excellent nom pour un débogueur
Sous Linux, on ne peut pas directement terminer un autre programme uniquement avec des sockets, mais avec les privilèges
root, on peut tuer d'autres processus, voire redémarrer la machinerootsont courants, donc ce risque existeCela va quelque peu à l'encontre de la sagesse traditionnelle des systèmes réseau : « soyez tolérant dans ce que vous acceptez et strict dans ce que vous émettez »