sandbox_architecture.tex 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. Dans la suite, nous allons considérer que chaque processus représente une zone
  2. de privilège, définissant ainsi ses accès et/ou permissions. Je vais alors
  3. décrire l'architecture que j'ai conçue pour organiser ces processus et garder
  4. une exécution aussi proche que possible que dans l'approche multithread.
  5. \section{La notion d'étage}
  6. L'architecture que nous allons construire se place contextuellement dans celle
  7. de VLC. Elle se base fortement sur la réalisation d'un pipeline de traitement
  8. dynamique, créé au fur et à mesure de la lecture des flux multimédia.
  9. Les différents éléments de ce pipeline seront créés éventuellement dans la même
  10. zone de privilège, éventuellement dans une zone de privilège déjà existante ou
  11. même donnera lieu à la création d'une nouvelle zone de privilège. Pour désigner
  12. ce concept du côté de l'API publique de la sandbox, on crée la notion d'étage,
  13. ou «stages», qui permet de ne pas forcément indiquer comment sera créée la
  14. partie du pipeline demandée par le client.
  15. L'étage représente donc une abstraction utilisée par la partie «VLC» mais
  16. réellement manipulée par la partie «sandbox» du processus en question.
  17. \section{Le modèle broker}
  18. Dans ce modèle, on considère un processus privilégié qu'on appelle broker, qui
  19. va contrôler tous les échanges entre les différents processus qu'on appelle
  20. workers, mais également leur cycle de vie et leurs permissions et accès.
  21. %TODO: schéma broker-worker
  22. Le broker est donc en charge de faire le routage des différents messages, de
  23. transmettre les ressources et faire la vérification d'accès. Il est également
  24. utile pour vérifier que les processus workers sont encore en vie et signaler les
  25. erreurs.
  26. % TODO: expliquer IPC
  27. Les avantages du modèle broker sont qu'il est généralement le modèle le plus
  28. simple à implémenter, et n'a pas besoin de fonctionnalité particulière du point
  29. de vue du système, à part pour créer les communications inter-processus (IPC).
  30. Nous pouvons même simuler toutes les problématiques d'accès par des jetons
  31. d'accès représenté par une certaine IPC, que le broker associera à un accès réel
  32. et reproduira les actions demandées par le worker. Il est également bien plus
  33. simple à comprendre, à développer, à isoler et à suivre étant donné que tous les
  34. échanges passent par le broker avant d'être transmis au bon processus. Ce modèle
  35. constitue ainsi un cadre privilégié pour développer la sandbox et l'amener sur
  36. tous les systèmes, à condition de garder en tête les contraintes des autres
  37. modèles.
  38. Le processus broker sera initialisé dans le processus principal et sera donc
  39. père de tous les autres processus de la sandbox. Cela permettra d'utiliser des
  40. techniques comme \texttt{ptrace} sous Linux ou de pouvoir créer des objets
  41. destinés aux processus fils et de leur associer des droits d'accès sous Windows
  42. sans avoir à recourir à des droits de superutilisateur.
  43. \section{Le modèle orchestrateur}
  44. Dans ce modèle, on considère un processus privilégié qu'on appelle
  45. orchestrateur. Celui-ci n'est plus au centre des communications inter-processus
  46. mais permet d'initialiser les connexions entre deux workers qui vont ensuite
  47. discuter directement. On doit donc s'attendre à de meilleures performances étant
  48. donné qu'on diminue les changements de contexte et appels systèmes. On garde cet
  49. «orchestrateur» pour initialiser chaque nouvel étage mais les modules peuvent
  50. fonctionner indépendamment après, du moment que tous les éléments qui
  51. sont liés à l'étage ont été créés.
  52. Ce modèle nécessite la possibilité d'initialiser une IPC entre deux workers qui
  53. doivent communiquer, mais potentiellement aussi mettre en place une autre IPC
  54. plus efficace pour les transferts de données du pipeline, commme des mémoire
  55. partagées. Il faut également que dans ce modèle, les workers ne puissent pas
  56. récupérer les droits des autres workers.
  57. C'est grâce à ce modèle qu'on peut mettre en valeur la puissance d'expression et
  58. de contrôle des jetons d'accès, car aucun contrôle de l'orchestrateur n'est
  59. nécessaire pour appliquer une réduction des privilèges et définir précisément
  60. les accès disponibles dans chaque partie du pipeline par conception plutôt que
  61. par des règles et contrôles d'accès.
  62. %TODO: schéma orchestrateur-worker
  63. \section{Les processus worker}
  64. %TODO: décrire rôle du processus worker
  65. Dans les deux modèles précédents, on a utilisé des processus workers qui vont
  66. avoir le même rôle, mais éventuellement des implémentations différentes.
  67. Chaque worker est équipé d'un thread jouant le rôle de boucle événementielle et
  68. récupérant les messages soit de tous les autres modules connectés, soit depuis
  69. le broker uniquement selon le modèle utilisé. La boucle événementielle sera
  70. décrite plus tard.
  71. Les workers peuvent démarrer de plusieurs façons. Soit un nouveau processus est
  72. créé en étant configuré comme un worker, avec des IPC correctes déjà attribuées.
  73. Soit le processus est créé depuis un fork et le thread worker peut démarrer tout
  74. de suite en ayant connaissance de son IPC vers l'orchestrateur ou le broker. La
  75. seconde option peut notamment apparaître lorsqu'un processus Zygote est utilisé.
  76. \section{La notion de processus Zygote}
  77. Afin d'optimiser le démarrage de nouveaux processus, beaucoup de systèmes
  78. utilisent un processus spécial, appelé «Zygote». Ce processus est responsable de
  79. créer les nouveaux processus et permet un démarrage plus rapide en
  80. préchargeant toutes les bibliothèques et préparant toutes les initialisations
  81. au préalable.
  82. % TODO expliquer et détailler ASLR et android
  83. Les nouveaux processus sont alors créés à partir d'un appel système
  84. \inltype{fork} qui est moins coûteux que la création complète d'un processus
  85. depuis rien. Mais n'est pas officiellement disponible sous Windows,
  86. officieusement disponible sur les versions Windows 10 via les détails internes
  87. liés à l'implémentation des pico-processus, et ne permet pas de pouvoir
  88. efficacement faire de l'ASLR entre les différents processus de l'application. Ce
  89. dernier point existe notamment sur Android, même si des mitigations existent.
  90. Le processus Zygote permet également d'efficacement cloisonner les descripteurs
  91. de fichier à hériter. Mais cela peut être préférée à une méthode plus
  92. systématique de libération de tous les descripteurs associés au processus si
  93. l'on ne souhaite pas utiliser ce processus pour des raisons de performances
  94. également.
  95. Néanmoins, l'autre partie très intéressante du Zygote concerne le débogage de la
  96. sandbox. Sous Linux, \texttt{gdb} n'est capable de s'accrocher qu'à un seul
  97. processus à la fois. Il faut alors choisir avec \texttt{set follow-fork-mode} si
  98. l'on veut déboguer le processus parent ou bien le processus enfant lors d'un
  99. appel à \inltype{fork}. Dans l'architecture que j'ai construite, nous réalisons
  100. les opérations de façon synchrone, même entre deux processus, ce qui permettra
  101. d'attacher des débogueurs au processus Zygote et basculer directement sur le
  102. processus enfant à chaque création de nouveau processus.