L'API en bac à sable (SAPI, Sandboxed API) s'appuie sur le projet Sandbox2 bien établi Sandbox2. Cette page explique l'architecture de conception de SAPI et les concepts clés.
Présentation
SAPI est conçu pour fournir aux développeurs des outils permettant de préparer les bibliothèques C/C++ pour l'exécution en bac à sable, ainsi que les API nécessaires à la communication avec la version en bac à sable des bibliothèques C/C++.
Ce schéma illustre l'architecture d'une bibliothèque C/C++ en bac à sable SAPI :

SAPI fournit également des primitives pour la synchronisation manuelle et automatique (basée sur des attributs de pointeur personnalisés) de la mémoire (tableaux, structures) entre les bibliothèques SAPI et le code hôte.
Enfin, une API de transactions de haut niveau permet de surveiller les bibliothèques SAPI et de les redémarrer en cas d'échec (par exemple, en raison de violations de sécurité, de plantages ou d'une utilisation excessive des ressources).
Sandbox2
Le projet Open Source Sandbox2 est développé et géré par des ingénieurs en sécurité de Google. Il s'agit de la technologie d'exécution en bac à sable de base utilisée par SAPI. Sandbox2 contient trois composants principaux : la stratégie de bac à sable, l'exécuteur et le bac à sable.
Stratégie de bac à sable
La stratégie de bac à sable définit l'environnement d'exécution restreint pour la bibliothèque en bac à sable. Pour ce faire, elle précise les appels système qui peuvent être exécutés. SAPI utilise le même mécanisme que Sandbox2. Pour en savoir plus sur la conception et la définition d’une stratégie de bac à sable, consultez la section Stratégie de bac à sable et la page Premiers pas avec Sandbox2.
Par défaut, les classes de bac à sable SAPI générées s'initialisent à l'aide de
DefaultConfig
(sapi::SandboxConfig::DefaultConfig()). DefaultConfig() configure le
bac à sable avec les éléments suivants :
- Une stratégie Sandbox2 par défaut créée avec
sapi::Sandbox2Config::DefaultPolicyBuilder() - Des limites de ressources et de temps par défaut provenant de
sapi::Sandbox2Config::DefaultLimits() - La communication de mémoire partagée activée (associée aux autorisations de mémoire partagée dans
DefaultPolicyBuilder()) - Des indicateurs de ligne de commande par défaut (
sapi::SandboxConfig::DefaultFlags()) et des variables d'environnement (sapi::SandboxConfig::DefaultEnvironmentVariables()), qui configurent la journalisation de base et le comportement d'exécution dans le bac à sable
Pour personnaliser la stratégie ou la configuration du bac à sable, commencez par
sapi::SandboxConfig::DefaultConfig(), modifiez le
sapi::SandboxConfig renvoyé et transmettez-le au constructeur de bac à sable généré (ou
définissez une sous-classe de bac à sable personnalisée dans un fichier d'en-tête sandbox.h transmis à la règle de compilation
sapi_library
). Par exemple, vous pouvez créer une stratégie à partir de
sapi::Sandbox2Config::DefaultPolicyBuilder() et enchaîner des règles supplémentaires (ou
créer un
PolicyBuilder
directement lorsqu'une configuration plus restrictive est requise). Lorsque vous ajoutez des
indicateurs ou des variables d'environnement, commencez par sapi::SandboxConfig::DefaultFlags()
ou sapi::SandboxConfig::DefaultEnvironmentVariables() afin de conserver les paramètres de base.
Bibliothèque en bac à sable
Il s'agit de la bibliothèque C/C++ en bac à sable qui sera exécutée dans l'environnement de bac à sable restreint fourni par Sandbox2. En fin de compte, la bibliothèque en bac à sable expose les fonctionnalités requises qui peuvent être utilisées par le code hôte.
La bibliothèque en bac à sable est créée avec la sapi_library sapi_library, dans laquelle vous pouvez spécifier une stratégie de bac à sable personnalisée qui définit l' environnement d'exécution restreint. Selon la bibliothèque, vous devrez peut-être écrire du code wrapper ou stub (voir libcurl), mais vous n'êtes pas censé modifier le code source de la bibliothèque C/C++ lors de la préparation de la version SAPI.
Objet SAPI et stub RPC
L'objet SAPI est un objet C++ qui expose l'API de la bibliothèque en bac à sable. Il transfère les appels du code hôte au stub RPC, qui est intégré à la bibliothèque SAPI avec la bibliothèque en bac à sable.
Ces deux éléments sont générés automatiquement par le système de compilation à l'aide de la règle de compilation sapi_library(). SAPI est compatible avec deux systèmes de compilation : Bazel de Google
et CMake.
Code hôte
Le code hôte est ce qui implémente la logique fournie par la bibliothèque SAPI. C'est ce qui consommerait autrement la version non en bac à sable de la bibliothèque C/C++. Par conséquent, le code hôte appelle les fonctions exportées par la bibliothèque SAPI, en transmettant des données au bac à sable et en recevant des données de celui-ci.
Le code hôte doit être adapté pour utiliser la bibliothèque SAPI. Plus précisément, il n'est pas possible d'appeler les fonctions de la bibliothèque, car celle-ci réside dans un processus en bac à sable distinct. Par conséquent, SAPI fournit des outils qui créent un objet SAPI qui proxy les appels à une bibliothèque SAPI.
Concepts
Règles de compilation Bazel
Le projet SAPI fournit deux règles de compilation Bazel pour l'exécution en bac à sable d'une bibliothèque C/C++ :
sapi_library(): crée toutes les sorties nécessaires pour que la bibliothèque C/C++ soit exécutée en bac à sable en tant que bac à sable Sandbox2. La sortie de compilation peut être utilisée comme dépendance pour la règlecc_binary()utilisée pour compiler le binaire du code hôte.sapi_interface(): génère automatiquement l'en-tête qui peut être inclus dans le binaire du code hôte.
Pour obtenir une explication plus complète des règles de compilation, consultez Build Rules.
Variables
SAPI fournit un certain nombre de types spéciaux, appelés types SAPI, que nous vous recommandons d'utiliser dans le code hôte. La principale raison pour laquelle les types SAPI sont nécessaires est l'isolation des processus, et donc de la mémoire, entre le code hôte et la bibliothèque en bac à sable.
Pour obtenir une explication plus complète de ce sujet et une présentation de certains types SAPI couramment utilisés, consultez Variables.
Transactions
Comme expliqué ci-dessus, tout appel d'API à une bibliothèque en bac à sable est transmis via une couche RPC. Pour pouvoir gérer un échec sur cette couche, vous devez implémenter une gestion des erreurs appropriée. Le module de transaction SAPI fournit le mécanisme nécessaire pour s'assurer que tous les appels à une bibliothèque en bac à sable sont effectués sans aucun problème au niveau RPC ou sont renvoyés avec une erreur pertinente.
Pour obtenir une explication plus complète de ce sujet, consultez Transactions.
Premiers pas
Consultez notre page Premiers pas pour configurer votre premier projet d'API en bac à sable.