1 points par GN⁺ 2024-04-28 | 1 commentaires | Partager sur WhatsApp

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

 
GN⁺ 2024-04-28
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_FAULT et aux vulnérabilités qui pourraient en découler

    • Il faut vérifier si, dans une situation où A attend B et B attend C, un REPLY_FAULT de C entraîne aussi la terminaison de A
    • Si c'est le cas, l'ensemble du système pourrait devenir vulnérable
    • Si SEND forme une structure cyclique, il pourrait même arriver qu'un processus se termine lui-même involontairement
  • REPLY_FAULT fournit un moyen de définir et d'implémenter des erreurs spécifiques à l'application, comme le contrôle d'accès

    • C'est utile quand le système est petit, étroitement intégré, et que le concepteur du système écrit lui-même la plupart des applications
    • En revanche, lors de l'intégration de code tiers, cela inquiète car l'autre partie peut mettre fin instantanément au processus à tout moment
    • Il existe dans le monde beaucoup de pilotes et de processus en arrière-plan médiocres, écrits par des développeurs malmenés par les administrateurs
  • Dans 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

    • Cela complique la réutilisation et la composition du code, mais simplifie le modèle d'exécution
    • Dans des systèmes embarqués statiques, cela peut constituer le bon compromis
  • 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 »

    • Cela convient bien à un contexte du type « quoi... mais en fait, pas mal »
  • 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

    • Il n'y a aucun intérêt pour un environnement d'exploitation qui ne tolère absolument aucun désordre du monde réel
  • Humility est un excellent nom pour un débogueur

    • Beaucoup de programmeurs refusent d'utiliser un débogueur en partant du principe qu'un « bon » code ne devrait pas nécessiter de débogage
  • 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 machine

    • Dans les conteneurs, les privilèges root sont courants, donc ce risque existe
  • Cela 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 »

    • Cependant, lorsqu'on modifie une API tout en maintenant la compatibilité avec les programmes existants, on est inévitablement obligé d'être tolérant à la réception