1. Memilih Metode Sandbox Executor

Sandbox dimulai dengan executor (lihat Sandbox Executor), yang bertanggung jawab untuk menjalankan Sandboxee. File header executor.h berisi API yang diperlukan untuk tujuan ini. API ini sangat fleksibel dan memungkinkan Anda memilih opsi yang paling sesuai dengan kasus penggunaan Anda. Bagian berikut menjelaskan 3 metode berbeda yang dapat Anda pilih.

Metode 1: Mandiri – Mengeksekusi biner dengan sandbox yang sudah diaktifkan

Ini adalah cara paling sederhana untuk menggunakan sandbox dan merupakan metode yang direkomendasikan jika Anda ingin membuat sandbox untuk seluruh biner yang tidak memiliki kode sumber. Cara ini juga merupakan cara paling aman untuk menggunakan sandbox, karena tidak ada inisialisasi tanpa sandbox yang dapat menimbulkan efek buruk.

Dalam cuplikan kode berikut, kita menentukan jalur biner yang akan di-sandbox dan argumen yang harus kita teruskan ke syscall execve. Seperti yang dapat Anda lihat di file header executor.h, kami tidak menentukan nilai untuk envp dan oleh karena itu menyalin lingkungan dari proses induk. Ingat, argumen pertama selalu berupa nama program yang akan dieksekusi, dan cuplikan kita tidak menentukan argumen lain.

Contoh metode executor ini adalah: static dan tool.

#include "sandboxed_api/sandbox2/executor.h"

std::string path = "path/to/binary";
std::vector<std::string> args = {path};  // args[0] will become the sandboxed
                                         // process' argv[0], typically the
                                         // path to the binary.
auto executor = absl::make_unique<sandbox2::Executor>(path, args);

Metode 2: Sandbox2 Forkserver – Memberi tahu eksekutor kapan harus di-sandbox

Metode ini menawarkan fleksibilitas untuk tidak di-sandbox selama inisialisasi, dan kemudian memilih waktu untuk memasuki sandbox dengan memanggil ::sandbox2::Client::SandboxMeHere(). Anda harus dapat menentukan dalam kode kapan Anda ingin memulai sandbox, dan sandbox harus berupa thread tunggal (baca alasannya di FAQ).

Dalam cuplikan kode berikut, kita menggunakan kode yang sama seperti yang diuraikan dalam Metode 1 di atas. Namun, agar program dapat dieksekusi tanpa sandbox selama inisialisasi, kita memanggil set_enable_sandbox_before_exec(false).

#include "sandboxed_api/sandbox2/executor.h"

std::string path = "path/to/binary";
std::vector<std::string> args = {path};
auto executor = absl::make_unique<sandbox2::Executor>(path, args);
executor->set_enable_sandbox_before_exec(false);

Karena executor kini memiliki sandbox yang dinonaktifkan hingga diberi tahu oleh Sandboxee, kita harus membuat instance ::sandbox2::Client, menyiapkan komunikasi antara executor dan Sandboxee, lalu memberi tahu executor bahwa inisialisasi kita telah selesai dan kita ingin memulai sandbox sekarang dengan memanggil sandbox2_client.SandboxMeHere().

// main() of sandboxee
int main(int argc, char** argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, false);

  // Set-up the sandbox2::Client object, using a file descriptor (1023).
  sandbox2::Comms comms(sandbox2::Comms::kSandbox2ClientCommsFD);
  sandbox2::Client sandbox2_client(&comms);
  // Enable sandboxing from here.
  sandbox2_client.SandboxMeHere();
  

Contoh metode eksekutor ini adalah crc4, dengan crc4bin.cc adalah Sandboxee dan memberi tahu eksekutor (crc4sandbox.cc) saat harus memasuki sandbox.

Metode 3: Forkserver Kustom – Siapkan biner, tunggu permintaan fork, dan sandbox sendiri

Mode ini memungkinkan Anda memulai biner, menyiapkan biner untuk sandbox, dan, pada saat tertentu dalam siklus proses biner, membuatnya tersedia untuk eksekutor.

Eksekutor akan mengirim permintaan fork ke biner Anda, yang akan fork() (melalui ::sandbox2::ForkingClient::WaitAndFork()). Proses yang baru dibuat akan siap di-sandbox dengan ::sandbox2::Client::SandboxMeHere().

#include "sandboxed_api/sandbox2/executor.h"

// Start the custom ForkServer
std::string path = "path/to/binary";
std::vector<std::string> args = {path};
auto fork_executor = absl::make_unique<sandbox2::Executor>(path, args);
fork_executor->StartForkServer();

// Initialize Executor with Comms channel to the ForkServer
auto executor = absl::make_unique<sandbox2::Executor>(
    fork_executor->ipc()->GetComms());

Perlu diingat bahwa mode ini cukup rumit dan hanya berlaku dalam beberapa kasus tertentu; misalnya, saat Anda memiliki persyaratan memori yang ketat. Anda akan mendapatkan manfaat dari COW, tetapi memiliki kekurangan karena tidak ada ASLR yang sebenarnya. Contoh penggunaan umum lainnya adalah saat Sandboxee memiliki inisialisasi yang panjang dan intensif CPU yang dapat dijalankan sebelum data yang tidak tepercaya diproses.

Untuk contoh metode executor ini, lihat custom_fork.