Z tej strony dowiesz się, jak utworzyć własną bibliotekę C/C++ w piaskownicy za pomocą interfejsu Sandboxed API (SAPI). Korzystaj z niego jako przewodnika wraz z przykładami i dokumentacją kodu w plikach nagłówkowych.
Zależności kompilacji
W systemie muszą być zainstalowane te zależności:
- Jądro systemu Linux z obsługą przestrzeni nazw UTS, IPC, użytkownika, PID i sieci
- Nagłówki interfejsu API przestrzeni użytkownika systemu Linux
- Do skompilowania kodu: GCC 6 (zalecana wersja 7 lub nowsza) lub Clang 7 (lub nowszy)
- Do automatycznego generowania plików nagłówkowych: Clang Python Bindings
- Python 3.5 lub nowszy
- Bazel w wersji 2.2.0 lub CMake w wersji 3.12 lub nowszej.
Korzystanie z Bazel
Bazel to zalecany system kompilacji, który najłatwiej zintegrować.
W naszej dokumentacji używamy kompilatora Clang. Jeśli potrzebujesz konkretnego łańcucha narzędzi (np. kompilatora, linkera itp.), zapoznaj się z dokumentacją Bazela, aby dowiedzieć się, jak zmienić domyślny łańcuch narzędzi kompilatora.
Debian 10 (Buster)
Aby zainstalować zależności kompilacji:
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt-get update
sudo apt-get install -qy build-essential linux-libc-dev bazel python3 \ python3-pip libclang-dev
pip3 install clang
Gentoo
Wymagane opcje jądra:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Aby zainstalować zależności kompilacji:
emerge dev-util/bazel dev-python/typing dev-python/clang-python
Korzystanie z CMake
CMake to popularny system metakompilacji typu open source, który generuje pliki projektu dla narzędzi do kompilacji, takich jak Ninja czy Make.
Debian 10 (Buster)
Aby zainstalować zależności kompilacji:
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \ python3 python3-pip libclang-dev libcap-dev
pip3 install absl-py clang
Gentoo
Wymagane opcje jądra:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Aby zainstalować zależności kompilacji:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-python
Proces programowania
Aby umieścić bibliotekę C/C++ w piaskownicy, musisz przygotować 2 elementy:
- Biblioteka w piaskownicy
- Kod hosta, który będzie korzystać z funkcji udostępnianych przez bibliotekę w piaskownicy. SAPI automatycznie wygeneruje obiekt SAPI i element RPC Stub podczas procesu kompilacji.
Możesz znać zlib z przykładów Sandbox2. W tym przypadku w piaskownicy umieszczono cały program (zpipe.c). Z poniższych kroków dowiesz się, jak używać interfejsu SAPI do testowania biblioteki zlib i korzystania z niej w środowisku testowym.
1. Określ, które funkcje są potrzebne.
Jeśli przyjrzysz się kodowi hosta zlib (main_zlib.cc), zobaczysz, że narzędzie odczytuje dane ze standardowego wejścia i używa funkcji deflate()
zlib do kompresowania danych do momentu odczytania znacznika EOF
.
Program korzysta łącznie z 3 funkcji biblioteki zlib:
deflateInit_()
: Inicjowanie kompresjideflate()
: aby przeprowadzić operację kompresji na bloku danych.deflateEnd()
: aby zakończyć kompresję i zwolnić dynamicznie przydzielone struktury danych.
W rzeczywistym przykładzie przejrzysz bibliotekę C/C++ i zdecydujesz, które funkcje są potrzebne. Możesz zacząć od kodu hosta i używać biblioteki bez piaskownicy. W drugim kroku możesz wygenerować bibliotekę w piaskownicy i dostosować kod hosta, aby używać wywołań funkcji w piaskownicy.
2. Napisz regułę kompilacji sapi_library
Po zidentyfikowaniu 3 funkcji zlib, które są potrzebne z biblioteki zlib w piaskownicy, możesz zdefiniować regułę kompilacji w pliku BUILD. Dokumentację reguły kompilacji sapi_library
znajdziesz na stronie Reguły kompilacji.
Poniższy fragment kodu pokazuje definicję sapi_library
dla przykładu SAPI zlib. Za pomocą atrybutu lib
Bazel otrzymuje instrukcję, aby szukać biblioteki zlib w pliku WORKSPACE.
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
W rezultacie powstaje biblioteka zlib w piaskownicy. Wynikiem jest obiekt SAPI, który można uwzględnić w kodzie hosta i używać do komunikacji z biblioteką w piaskownicy za pomocą wywołań RPC. Zasady piaskownicy użyte w tym przykładzie to zasady domyślne.
3. Pisanie lub zmienianie kodu hosta
Teraz możesz włączyć wygenerowaną bibliotekę SAPI do kodu hosta.
Tworzenie piaskownicy
Użyj sapi::Sandbox sandbox(sapi::zlib::zlib_sapi_embed_create());
, aby utworzyć obiekt
w środowisku piaskownicy.
Użyj sapi::zlib::ZlibApi api(&sandbox);
, aby utworzyć instancję obiektu SAPI, a tym samym udostępnić funkcje w piaskownicy do użycia.
Używanie typów SAPI
Typy SAPI to specjalne typy w postaci klas C++, które SAPI udostępnia, ponieważ czasami zwykłe typy C nie działają.
Pierwsze użycie typu SAPI można zaobserwować w deklaracji strm
, gdzie używana jest struktura SAPI: sapi::v::Struct<sapi::zlib::z_stream> strm;
Typ szablonu (sapi::zlib::z_stream
) to dobry przykład kodu wygenerowanego automatycznie przez regułę kompilacji.
Więcej informacji znajdziesz na stronie zmiennych.
Wywoływanie interfejsu API
Aby wykonywać połączenia na numery defalteInit_
, deflate
lub deflateEnd
, użyj obiektu SAPI. Jeśli zdecydujesz się na użycie podejścia „change”, musisz się upewnić, że parametry funkcji odpowiadają oczekiwanym wartościom.
Przykład każdego wywołania w zlib example:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION, version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
Korzystanie z transakcji SAPI
SAPI izoluje kod hosta od biblioteki w piaskownicy i umożliwia wywołującemu ponowne uruchomienie lub przerwanie problematycznych żądań przetwarzania danych. SAPI Transaction idzie o krok dalej i automatycznie powtarza procesy, które zakończyły się niepowodzeniem.
Więcej informacji znajdziesz na stronie transakcji SAPI.
Przykłady
W sekcji Przykłady znajdziesz kilka bibliotek przygotowanych przez zespół SAPI.