Bu sayfada, Sandboxed API (SAPI) ile kendi korumalı alan C/C++ kitaplığınızı nasıl oluşturacağınızı öğreneceksiniz. Bu dokümanı, üstbilgi dosyalarındaki örnekler ve kod dokümanlarıyla birlikte kılavuz olarak kullanın.
Derleme Bağımlılıkları
Sistemde aşağıdaki bağımlılıkların yüklü olması gerekir:
- UTS, IPC, kullanıcı, PID ve ağ ad alanlarını destekleyen Linux çekirdeği
- Linux kullanıcı alanı API başlıkları
- Kodunuzu derlemek için: GCC 6 (7 veya daha yeni bir sürüm tercih edilir) ya da Clang 7 (veya daha yeni bir sürüm)
- Üstbilgi dosyalarını otomatik olarak üretmek için: Clang Python Bindings
- Python 3.5 veya sonraki sürümler
- Bazel 2.2.0 veya CMake 3.12 ya da daha yeni bir sürüm.
Bazel'i kullanma
Bazel, önerilen derleme sistemidir ve entegrasyonu en kolay olanıdır.
Belgelerimizde Clang derleyicisi kullanılmaktadır. Belirli bir araç zincirine (ör. derleyici, bağlayıcı vb.) ihtiyacınız varsa varsayılan derleyici araç zincirini nasıl değiştireceğinizle ilgili bilgi için Bazel belgelerine bakın.
Debian 10 (Buster)
Derleme bağımlılıklarını yüklemek için:
echo "deb http://storage.googleapis.com/bazel-apt stable jdk1.8" | \ sudo tee /etc/apt/sources.list.d/bazel.listwget -qO - https://releases.bazel.build/bazel-release.pub.gpg | sudo apt-key add -sudo apt-get updatesudo apt-get install -qy build-essential linux-libc-dev bazel python3 \ python3-pip libclang-devpip3 install clang
Gentoo
Gerekli çekirdek seçenekleri:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Derleme bağımlılıklarını yüklemek için:
emerge dev-util/bazel dev-python/typing dev-python/clang-pythonCMake kullanma
CMake, Ninja veya Make gibi derleme araçları için proje dosyaları oluşturan popüler bir açık kaynaklı meta derleme sistemidir.
Debian 10 (Buster)
Derleme bağımlılıklarını yüklemek için:
sudo apt-get install -qy build-essential linux-libc-dev cmake ninja-build \ python3 python3-pip libclang-dev libcap-devpip3 install absl-py clang
Gentoo
Gerekli çekirdek seçenekleri:
General setup --->
-*- Namespaces support
[*] UTS namespace
[*] IPC namespace
[*] User namespace (EXPERIMENTAL)
[*] PID Namespaces
[*] Network namespace
Derleme bağımlılıklarını yüklemek için:
emerge sys-kernel/linux-headers dev-util/cmake dev-util/ninja \
dev-python/clang-pythonGeliştirme Süreci
Bir C/C++ kitaplığını korumalı alana almak için projenizle ilgili iki öğe hazırlamanız gerekir:
- Korumalı alan kitaplığı
- Ana makine kodu, Sandboxed Library'niz tarafından kullanıma sunulan işlevselliği kullanır. SAPI, derleme işlemi sırasında SAPI nesnesini ve RPC saplamasını sizin için otomatik olarak oluşturur.
Sandbox2 örneklerindeki zlib'e aşina olabilirsiniz. Burada tüm bir program (zpipe.c) korumalı alana alınmıştır. Aşağıdaki adımlarda, zlib kitaplığını korumalı alana almak ve korumalı alana alınmış kitaplığı kullanmak için SAPI'yi nasıl kullanacağınızı öğreneceksiniz.
1. Hangi işlevlerin gerekli olduğuna karar verme
zlib ana makine koduna (main_zlib.cc) bakarsanız aracın işlevinin, stdin'den veri okumak ve EOF işaretçisi okunana kadar verileri sıkıştırmak için zlib'in deflate() işlevini kullanmak olduğunu görebilirsiniz.
Program, zlib'den toplam üç işlev kullanır:
deflateInit_(): Sıkıştırma için ilk kullanıma hazırlamadeflate(): Veri parçasında sıkıştırma işlemini gerçekleştirmek içindeflateEnd(): Sıkıştırmayı sonlandırmak ve dinamik olarak ayrılan veri yapılarını serbest bırakmak için
Gerçek hayattan bir örnekte, C/C++ kitaplığını inceleyip hangi işlevlerin gerekli olduğuna karar verirsiniz. Olası bir strateji, Host Code ile başlayıp kitaplığı korumalı alan dışında kullanmaktır. Ardından, ikinci bir adımda, Sandboxed Library'yi oluşturabilir ve Host Code'u, korumalı alan işlevi çağrılarını kullanacak şekilde uyarlayabilirsiniz.
2. sapi_library derleme kuralını yazma
Koruma alanına alınmış zlib kitaplığından gereken üç zlib işlevini belirledikten sonra, BUILD dosyasında derleme kuralını tanımlayabilirsiniz. sapi_library derleme kuralıyla ilgili dokümanları Derleme Kuralları sayfasında bulabilirsiniz.
Aşağıdaki kod snippet'inde, zlib SAPI örneği için sapi_library tanımı gösterilmektedir. lib özelliği kullanılarak Bazel'e zlib kitaplığı için WORKSPACE dosyasına bakması talimatı verilir.
sapi_library(
name = "zlib-sapi",
srcs = [],
hdrs = [],
functions = [
"deflateInit_",
"deflate",
"deflateEnd",
],
lib = "@net_zlib//:zlib",
lib_name = "Zlib",
namespace = "sapi::zlib",
)
Sonuç olarak, korumalı alan zlib kitaplığı oluşturulur. Çıkış, ana makine koduna dahil edilebilen ve RPC çağrıları kullanarak korumalı alan kitaplığıyla iletişim kurmak için kullanılabilen SAPI nesnesidir.
Bu örnekte,
DefaultConfig
(sapi::SandboxConfig::DefaultConfig()) tarafından sağlanan varsayılan korumalı alan yapılandırması kullanılmaktadır.
3. Ana makine kodunu yazma veya değiştirme
Şimdi, oluşturulan SAPI kitaplığını ana makine koduna dahil etme zamanı.
Korumalı alanı oluşturma
sapi::zlib::ZlibSandbox sandbox; kullanarak bir
sandbox nesnesi oluşturun.
SAPI nesnesini örneklendirmek ve korumalı alana alınmış işlevleri kullanıma hazır hale getirmek için sapi::zlib::ZlibApi api(&sandbox); kullanın.
Korumalı alan politikasını, işaretleri, ortam değişkenlerini veya sınırları özelleştirmek için sapi::SandboxConfig::DefaultConfig() ile başlayın, ilgili alanları değiştirin (temel ayarların korunması için sapi::Sandbox2Config::DefaultPolicyBuilder(), sapi::SandboxConfig::DefaultFlags() veya sapi::SandboxConfig::DefaultEnvironmentVariables() kullanın) ve sapi::SandboxConfig öğesini korumalı alan oluşturucusuna iletin:
sapi::SandboxConfig config = sapi::SandboxConfig::DefaultConfig();
config.sandbox2.policy = sapi::Sandbox2Config::DefaultPolicyBuilder()
.AddFile("/path/to/file")
.BuildOrDie();
auto flags = sapi::SandboxConfig::DefaultFlags();
flags["my_flag"] = "value";
config.command_line_flags = std::move(flags);
sapi::zlib::ZlibSandbox sandbox(std::move(config));
SAPI Türlerini Kullanma
SAPI Türleri, SAPI'nin sağladığı C++ sınıfları biçimindeki özel türlerdir. Bunun nedeni, bazen normal C türlerinin çalışmamasıdır.
Bir SAPI türünün ilk kullanımı, strm bildiriminde gözlemlenebilir. Burada bir SAPI yapısı kullanılır: sapi::v::Struct<sapi::zlib::z_stream> strm;
Şablon türü (sapi::zlib::z_stream), derleme kuralı tarafından otomatik olarak oluşturulan kodun iyi bir örneğidir.
Daha fazla bilgi için Değişkenler sayfasına göz atın.
API çağrıları yapma
defalteInit_, deflate veya deflateEnd numaralarını aramak için SAPI
Object'i kullanın. "Değiştirme" yaklaşımını kullanmaya karar verirseniz işlev parametrelerinin beklenen değerlerle eşleştiğinden emin olmanız gerekir.
zlib örneğindeki çağrıların her birine örnek:
api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION, version.PtrBefore(), sizeof(sapi::zlib::z_stream));
api.deflate(strm.PtrBoth(), flush);
api.deflateEnd(strm.PtrBoth()).IgnoreError();
SAPI işlemlerini kullanma
SAPI, ana makine kodunu korumalı alana alınmış kitaplıktan ayırır ve arayana, sorunlu veri işleme isteklerini yeniden başlatma veya iptal etme olanağı verir. SAPI İşlemi bir adım daha ileri giderek başarısız olan işlemleri otomatik olarak tekrar eder.
Daha fazla bilgi için SAPI İşlemleri Sayfası'na göz atın.
Örnekler
Examples (Örnekler) bölümünde, SAPI ekibi tarafından hazırlanmış birkaç kitaplık bulabilirsiniz.