1. Memilih Metode Eksekutor Sandbox

Sandboxing dimulai dengan eksekutor (lihat Eksekutor Sandbox), 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 apa yang paling cocok untuk kasus penggunaan Anda. Bagian berikut menjelaskan 3 metode berbeda yang dapat Anda pilih.

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

Ini adalah cara paling sederhana untuk menggunakan sandbox dan merupakan metode yang disarankan jika Anda ingin melakukan sandbox seluruh biner yang kode sumbernya tidak Anda miliki. Metode ini juga merupakan cara paling aman untuk menggunakan sandbox karena tidak ada inisialisasi di luar sandbox yang dapat menimbulkan efek buruk.

Dalam cuplikan kode berikut, kita menentukan jalur biner yang akan di-sandbox dan argumen yang harus diteruskan ke syscall eksekutif. Seperti yang Anda lihat dalam file header executor.h, kita tidak menentukan nilai untuk envp sehingga kita akan menyalin lingkungan dari proses induk. Ingat, argumen pertama selalu merupakan nama program yang akan dieksekusi, dan cuplikan kita tidak mendefinisikan argumen lain.

Contoh metode eksekutor ini adalah: statis dan alat.

#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 melakukan sandbox selama inisialisasi, lalu memilih waktu untuk memasuki sandbox dengan memanggil ::sandbox2::Client::SandboxMeHere(). Anda harus dapat menentukan kode saat ingin memulai sandbox dan harus 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 dengan cara yang tidak di-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 sekarang eksekutor telah menonaktifkan sandbox hingga diberi tahu oleh Sandboxee, kita harus membuat instance ::sandbox2::Client, menyiapkan komunikasi antara eksekutor dan Sandboxee, lalu memberi tahu eksekutor bahwa inisialisasi 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) kapan harus masuk ke sandbox.

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

Mode ini memungkinkan Anda memulai biner, mempersiapkannya untuk sandbox, dan, pada saat tertentu dalam siklus proses biner Anda, menyediakannya 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 dapat diterapkan dalam beberapa kasus tertentu; misalnya, saat Anda memiliki kebutuhan memori yang ketat. Anda akan mendapatkan manfaat dari COW tetapi memiliki kelemahan bahwa tidak ada ASLR yang sebenarnya. Contoh penggunaan umum lainnya adalah ketika Sandboxee memiliki inisialisasi intensif CPU yang panjang yang dapat dijalankan sebelum data yang tidak tepercaya diproses.

Untuk contoh metode eksekutor ini, lihat custom_fork.