Questions fréquentes

Puis-je utiliser des threads ?

Oui, les threads sont compatibles avec Sandbox2.

Tous les threads doivent être mis en bac à sable

En raison du fonctionnement de Linux, la stratégie seccomp-bpf n'est appliquée qu'au thread actuel. Cela signifie que la stratégie n'est pas appliquée aux autres threads existants, mais que les futurs threads l'hériteront :

  • Si vous utilisez Sandbox2 dans le premier mode où la mise en bac à sable est activée avant execve(), tous les threads hériteront de la stratégie, et il n'y aura aucun problème. Il s'agit du mode de mise en bac à sable préféré.
  • Si vous utilisez le deuxième mode où l'exécuteur dispose de set_enable_sandbox_before_exec(false) et que le Sandboxee indique à l'exécuteur quand il souhaite être mis en bac à sable avec SandboxMeHere(), assurez-vous que le filtre est appliqué à tous les threads. Sinon, il existe un risque d'échappement du bac à sable : un code malveillant peut migrer d'un thread mis en bac à sable vers un thread non mis en bac à sable.

Comment compiler mon Sandboxee ?

Par rapport à un exécutable lié de manière statique, la compilation du Sandboxee dans un exécutable lié de manière dynamique entraînera une augmentation significative des appels système (par exemple, open/openat, mmap, etc.) qui doivent être ajoutés à la liste d'autorisation. Tous ces appels système supplémentaires sont nécessaires en raison de l'appel du linker dynamique au moment de l'exécution pour charger les bibliothèques partagées.

Toutefois, en ce qui concerne les Sandboxees liés de manière statique, bien que moins d'appels système doivent être ajoutés à la liste d'autorisation, il existe également des implications en termes de sécurité. L'entropie du tas ASLR est réduite (de 30 bits à 8 bits), ce qui facilite les exploits.

Il s'agit d'un dilemme qui peut essentiellement être réduit à :

  • Dynamique : bon ASLR de tas de mémoire, potentiellement plus difficile à obtenir l'exécution de code initiale, mais au prix d'une stratégie de bac à sable moins efficace, potentiellement plus facile à contourner.
  • Statique : mauvais ASLR de tas, potentiellement plus facile à obtenir l'exécution initiale du code mais une stratégie de bac à sable plus efficace, potentiellement plus difficile à contourner.

Historiquement, les binaires liés de manière statique ne prenaient pas en charge le code indépendant de la position (pie). De plus, Bazel a ajouté pie par défaut. Pour pouvoir définir un filtre d'appel système strict, vous deviez remplacer la valeur par défaut de Bazel.

Les compilateurs se sont améliorés au fil des ans et prennent désormais en charge une option static-pie. Avec cette option, un compilateur est chargé de générer du code indépendant de la position, mais contrairement à pie, il inclut désormais également toutes les bibliothèques liées de manière statique. D'un point de vue sécurité, static-pie réduit toujours l'entropie ASLR (de 30 bits à 14 bits), mais il s'agit d'une amélioration par rapport à la situation précédente sans pie.

Comme Bazel ajoute pie par défaut et que le statique n'est pas compatible avec lui, envisagez d'utiliser l'indicateur d'options de l'éditeur de liens pour transmettre l'indicateur de l'éditeur de liens -static-pie au cc_binary règle et remplacer la valeur par défaut :

  linkstatic = 1,
  linkopts=["-static-pie"],

Pour obtenir un exemple de ces options, consultez l'exemple statique BUILD : static_bin.cc est lié de manière statique à static-pie, ce qui permet d'avoir une stratégie d'appel système très stricte. Cela fonctionne également bien pour la mise en bac à sable des binaires tiers.

Puis-je mettre en bac à sable des binaires x86 32 bits ?

Sandbox2 ne peut mettre en bac à sable que la même architecture que celle avec laquelle il a été compilé.

De plus, la prise en charge de x86 32 bits a été supprimée de Sandbox2. Si vous essayez d'utiliser un exécuteur x86 64 bits pour mettre en bac à sable un binaire x86 32 bits, ou un binaire x86 64 bits effectuant des appels système 32 bits (via int 0x80), les deux génèrent une violation de bac à sable qui peut être identifiée par le libellé d'architecture [X86-32].

La raison de ce comportement est que les numéros d'appel système diffèrent entre les architectures. Étant donné que la stratégie d'appel système est écrite dans l'architecture de l'exécuteur, il serait dangereux d'autoriser une architecture différente pour le Sandboxee. En effet, cela pourrait entraîner l'autorisation d'un appel système apparemment inoffensif qui, en fait, signifie qu'un autre appel système plus dangereux pourrait ouvrir le bac à sable à une échappatoire.

Existe-t-il des limites au nombre de bacs à sable qu'un processus d'exécuteur peut demander ?

Pour chaque instance Sandboxee (nouveau processus généré à partir du forkserver), un nouveau thread est créé. C'est là que réside la limite.

Un exécuteur peut-il demander la création de plusieurs bacs à sable ?

Non. Il existe une relation 1:1 : une instance d'exécuteur stocke le PID du Sandboxee, gère l'instance Comms dans l'instance Sandbox, etc.

Pourquoi le message "Function not implemented" (Fonction non implémentée) s'affiche-t-il dans forkserver.cc ?

Sandbox2 n'est compatible qu'avec les noyaux relativement récents. Notre limite actuelle est le noyau 3.19, mais cela pourrait changer à l'avenir. En effet, nous utilisons des fonctionnalités de noyau relativement nouvelles, y compris les espaces de noms utilisateur et seccomp avec l'indicateur TSYNC.

Si vous exécutez en production, cela ne devrait pas poser de problème, car la quasi-totalité de la flotte exécute un noyau suffisamment récent. Si vous rencontrez des problèmes, veuillez nous contacter.

Si vous exécutez Debian ou Ubuntu, la mise à jour de votre noyau est aussi simple que l'exécution de :

sudo apt-get install linux-image-<RECENT_VERSION>