Wyjaśnienie interfejsu API piaskownicy

Interfejs Sandboxed API (SAPI) jest oparty na dobrze znanym Sandbox2. Na tej stronie znajdziesz informacje o architekturze SAPI i najważniejszych pojęciach.

Przegląd

SAPI ma na celu udostępnienie deweloperom narzędzi do przygotowywania bibliotek C/C++ do umieszczania w piaskownicy oraz interfejsów API niezbędnych do komunikacji z wersją bibliotek C/C++ w piaskownicy.

Ten diagram przedstawia architekturę biblioteki C/C++ w piaskownicy SAPI:

Diagram SAPI

SAPI udostępnia też elementy pierwotne do ręcznej i automatycznej (na podstawie niestandardowych atrybutów wskaźnika) synchronizacji pamięci (tablic, struktur) między bibliotekami SAPI a kodem hosta.

Na koniec, interfejs API transakcji wysokiego poziomu umożliwia monitorowanie bibliotek SAPI i ponowne uruchamianie ich w przypadku awarii (np. z powodu naruszeń bezpieczeństwa, awarii lub wyczerpania zasobów).

Sandbox2

Projekt open source Sandbox2 jest rozwijany i utrzymywany przez inżynierów ds. bezpieczeństwa Google i jest podstawową technologią piaskownicy używaną przez SAPI. Sandbox2 zawiera 3 główne komponenty: zasady piaskownicy, wykonawcę i piaskownicę.

Zasady piaskownicy

Zasady piaskownicy określają ograniczone środowisko wykonawcze dla biblioteki w piaskownicy. Jest to możliwe dzięki określeniu, które wywołania systemowe mogą być wykonywane. SAPI używa tego samego mechanizmu co Sandbox2. Więcej informacji o projektowaniu i definiowaniu zasad piaskownicy znajdziesz w sekcji Zasady piaskownicy i na stronie Pierwsze kroki w Sandbox2.

Domyślnie wygenerowane klasy piaskownicy SAPI są inicjowane za pomocą DefaultConfig (sapi::SandboxConfig::DefaultConfig()). DefaultConfig() konfiguruje piaskownicę w następujący sposób:

  • Domyślne zasady Sandbox2 utworzone za pomocą sapi::Sandbox2Config::DefaultPolicyBuilder()
  • Domyślne limity zasobów i czasu z sapi::Sandbox2Config::DefaultLimits()
  • Włączona komunikacja w pamięci współdzielonej (w połączeniu z uprawnieniami do pamięci współdzielonej w DefaultPolicyBuilder())
  • Domyślne flagi wiersza poleceń (sapi::SandboxConfig::DefaultFlags()) i zmienne środowiskowe (sapi::SandboxConfig::DefaultEnvironmentVariables()), które konfigurują podstawowe logowanie i działanie w czasie wykonywania w piaskownicy

Aby dostosować zasady lub konfigurację piaskownicy, zacznij od sapi::SandboxConfig::DefaultConfig(), zmodyfikuj zwrócony sapi::SandboxConfig, i przekaż go do wygenerowanego konstruktora piaskownicy (lub zdefiniuj niestandardową podklasę piaskownicy w pliku nagłówkowym sandbox.h przekazanym do reguły kompilacji sapi_library ). Możesz na przykład utworzyć zasady, zaczynając od sapi::Sandbox2Config::DefaultPolicyBuilder() i połączyć dodatkowe reguły (lub bezpośrednio utworzyć PolicyBuilder , gdy wymagana jest bardziej restrykcyjna konfiguracja). Podczas dodawania flag lub zmiennych środowiskowych zacznij od sapi::SandboxConfig::DefaultFlags() lub sapi::SandboxConfig::DefaultEnvironmentVariables(), aby zachować ustawienia podstawowe .

Biblioteka w piaskownicy

Jest to biblioteka C/C++ w piaskownicy, która będzie wykonywana w ograniczonym środowisku piaskownicy udostępnianym przez Sandbox2. Biblioteka w piaskownicy udostępnia wymagane funkcje, które mogą być używane przez kod hosta.

Biblioteka w piaskownicy jest tworzona za pomocą reguły kompilacji sapi_library, w której możesz określić dostosowane zasady piaskownicy definiujące ograniczone środowisko wykonawcze. W zależności od biblioteki może być konieczne napisanie kodu otoki lub kodu zastępczego (patrz libcurl), ale podczas przygotowywania wersji SAPI nie musisz zmieniać kodu źródłowego biblioteki C/C++.

Obiekt SAPI i kod zastępczy RPC

Obiekt SAPI to obiekt C++, który udostępnia interfejs API biblioteki w piaskownicy. Przekazuje wywołania z kodu hosta do kodu zastępczego RPC, który jest osadzony w bibliotece SAPI wraz z biblioteką w piaskownicy.

Te 2 elementy są generowane automatycznie przez system kompilacji za pomocą reguły kompilacji sapi_library(). SAPI obsługuje 2 systemy kompilacji: Google's Bazel i CMake.

Kod hosta

Kod hosta implementuje logikę udostępnianą przez bibliotekę SAPI. W przeciwnym razie używałby wersji biblioteki C/C++ bez piaskownicy. Kod hosta wywołuje funkcje eksportowane przez bibliotekę SAPI, przekazując dane do piaskownicy i odbierając z niej dane.

Kod hosta musi być dostosowany do używania biblioteki SAPI. W szczególności wywoływanie funkcji biblioteki nie jest możliwe, ponieważ biblioteka znajduje się w osobnym procesie w piaskownicy. Dlatego SAPI udostępnia narzędzia, które tworzą obiekt SAPI, który przekazuje wywołania do biblioteki SAPI.

Pojęcia

Reguły kompilacji Bazel

Projekt SAPI udostępnia 2 reguły kompilacji Bazel do umieszczania biblioteki C/C++ w piaskownicy:

  • sapi_library() – tworzy wszystkie dane wyjściowe niezbędne do umieszczenia biblioteki C/C++ w piaskownicy jako piaskownicy Sandbox2. Dane wyjściowe kompilacji mogą być używane jako zależność reguły cc_binary() używanej do kompilowania kodu hosta.
  • sapi_interface() – automatycznie generuje nagłówek, który można uwzględnić w kodzie hosta.

Bardziej szczegółowe wyjaśnienie reguł kompilacji znajdziesz w artykule Build Rules.

Zmienne

SAPI udostępnia kilka specjalnych typów, zwanych typami SAPI, których zalecamy używać w kodzie hosta. Głównym powodem, dla którego potrzebne są typy SAPI, jest izolacja procesu, a tym samym pamięci, między kodem hosta a biblioteką w piaskownicy.

Bardziej szczegółowe wyjaśnienie tego tematu i omówienie niektórych często używanych typów SAPI znajdziesz w artykule Zmienne.

Transakcje

Jak wyjaśniono powyżej, każde wywołanie interfejsu API do biblioteki w piaskownicy jest przekazywane przez warstwę RPC. Aby móc obsługiwać awarie w tej warstwie, musisz zaimplementować odpowiednią obsługę błędów. Moduł transakcji SAPI udostępnia mechanizm, który zapewnia, że wszystkie wywołania biblioteki w piaskownicy są wykonywane bez problemów na poziomie RPC lub zwracają odpowiedni błąd.

Bardziej szczegółowe wyjaśnienie tego tematu znajdziesz w artykule Transakcje.

Pierwsze kroki

Aby skonfigurować pierwszy projekt Sandboxed API, przeczytaj stronę Pierwsze kroki.