Questions fréquentes

Puis-je utiliser des threads ?

Oui, les threads sont compatibles avec Sandbox2.

Tous les threads doivent être en bac à sable

En raison du fonctionnement de Linux, la règle seccomp-bpf ne s'applique qu'au thread actuel. Cela signifie qu'elle n'est pas appliquée aux autres threads existants, mais les futurs threads en hériteront :

  • Si vous utilisez le bac à sable 2 en premier mode où le bac à sable est activé avant le execve(), tous les threads hériteront de la règle, et il n'y a aucun problème. Il s'agit du mode de bac à sable à privilégier.
  • Si vous utilisez le deuxième mode où l'exécuteur dispose de set_enable_sandbox_before_exec(false) et que Sandboxee indique à l'exécuteur qu'il souhaite passer en bac à sable avec SandboxMeHere(), assurez-vous que le filtre est appliqué à tous les threads. Sinon, vous risquez de vous échapper d'un bac à sable: du code malveillant peut migrer d'un thread en bac à sable vers un thread sans bac à sable.

Comment compiler mon Sandboxee ?

Si vous ne faites pas attention, il est facile d'hériter d'un grand nombre de dépendances et d'effets secondaires (appels système supplémentaires, accès aux fichiers ou même connexions réseau) qui rendent le bac à sable plus difficile (suivi de tous les effets secondaires) et moins sûr (car les règles des appels système et des fichiers sont plus larges). Certaines options de compilation peuvent vous aider à réduire ces problèmes:

  • Compilez de manière statique le binaire Sandboxee pour éviter les liens dynamiques qui utilisent beaucoup d'appels système (open/openat, mmap, etc.).
  • Étant donné que Bazel ajoute pie par défaut, mais l'option statique n'est pas compatible, envisagez d'utiliser l'indicateur de fonctionnalités pour le forcer à l'aide des options suivantes dans les règles cc_binary:

    linkstatic = 1,
    features = [
        "fully_static_link",  # link libc statically
        "-pie",
    ],
    

Néanmoins:l'utilisation de la couche statique a pour inconvénient de réduire l'entropie du tas de mémoire ASLR (de 30 bits à 8 bits), ce qui facilite les failles. Choisissez soigneusement ce qui est préférable en fonction de la mise en œuvre et des règles de votre bac à sable:

  • non statique : bonne réponse ASLR au niveau du tas de mémoire : il est potentiellement plus difficile d'exécuter le code initial, mais au prix d'une stratégie de bac à sable moins efficace, ce qui peut être plus facile à sortir.
  • statique: ASLR sur un tas de mémoire incorrect. Il est potentiellement plus facile d'obtenir l'exécution initiale du code, mais il s'agit d'une stratégie de bac à sable plus efficace, qui est potentiellement plus difficile à extraire.

Ce choix est regrettable, car le compilateur n'est pas compatible avec le format PIE (Position Independent Executables) statique. Pour implémenter PIE, le binaire doit être un objet dynamique. Le chargeur dynamique le mappe à un emplacement aléatoire avant de l'exécuter. Ensuite, comme le tas de mémoire est traditionnellement placé à un décalage aléatoire après l'adresse de base du binaire (et étendu avec brk syscall), cela signifie que pour les binaires statiques, l'entropie ASLR du tas de mémoire n'est que ce décalage, car il n'y a pas de PIE.

Pour obtenir des exemples de ces options de compilation, consultez l'exemple statique de BUILD.bazel: static_bin.cc est compilé de manière statique, ce qui nous permet d'avoir une stratégie d'appel système très stricte. Cela fonctionne également bien avec le bac à sable de binaires tiers.

Puis-je effectuer un bac à sable pour des binaires x86 32 bits ?

Le bac à sable 2 n'est compatible qu'avec la même architecture que celle avec laquelle il a été compilé.

De plus, le bac à sable 2 n'est plus compatible avec x86 32 bits. Si vous essayez d'utiliser un exécuteur x86 64 bits pour créer le bac à sable d'un binaire x86 32 bits ou d'un binaire x86 64 bits effectuant des appels système 32 bits (via int 0x80), les deux génèrent un cas de non-respect du bac à sable, identifiable par l'étiquette d'architecture [X86-32].

La raison de ce comportement est que le nombre d'appels système diffère d'une architecture à l'autre. La règle des appels système étant écrite dans l'architecture de l'exécuteur, il serait dangereux d'autoriser une architecture différente pour Sandboxee. En effet, cela pourrait permettre d'autoriser un appel système apparemment inoffensif, qui signifie qu'un autre appel système plus nuisible pourrait permettre d'échapper au bac à sable.

Le nombre de bacs à sable qu'un processus d'exécuteur peut demander est-il limité ?

Pour chaque instance Sandboxee (un nouveau processus généré à partir du serveur forkserver), un 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 exécuteur stocke le PID du bac à sable, gère l'instance Comms avec l'instance bac à sable, etc.

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

Le bac à sable 2 n'est compatible qu'avec des noyaux relativement nouveaux. Notre arrêt actuel est le noyau 3.19, bien que cela pourrait changer à l'avenir. La raison à cela est que nous utilisons des fonctionnalités de noyau relativement récentes, notamment les espaces de noms utilisateur et seccomp avec l'indicateur TSYNC.

Si vous exécutez en production, cela ne devrait pas être un problème, puisque la quasi-totalité du parc exécute un noyau suffisamment récent. Si vous rencontrez des problèmes, veuillez nous contacter.

Si vous utilisez Debian ou Ubuntu, la mise à jour du noyau est aussi simple que d'exécuter:

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