Sandbox Linux dan Fil-C
(fil-c.org)- Keamanan memori dan sandboxing adalah konsep keamanan yang saling independen, dan keduanya harus dimiliki untuk membentuk sistem pertahanan yang kuat
- Fil-C adalah implementasi aman memori untuk C/C++, yang menjamin keamanan hingga tingkat system call Linux dan dapat digunakan bahkan pada komponen sistem seperti OpenSSH
- Dalam proses mem-porting sandbox berbasis seccomp-BPF milik OpenSSH ke Fil-C, pembatasan pembuatan thread dan penyesuaian filter seccomp menjadi tantangan utama
- Untuk pengelolaan thread latar belakang pada runtime Fil-C, ditambahkan API
zlock_runtime_threads()untuk mengendalikan perilaku thread di dalam sandbox - Fil-C mengimplementasikan sinkronisasi penerapan pemanggilan
prctlke semua thread runtime, agar no_new_privs dan filter seccomp diterapkan secara konsisten ke seluruh proses
Hubungan antara keamanan memori dan sandboxing
- Keamanan memori dan sandboxing adalah dua lapisan keamanan yang berbeda; hanya memiliki salah satunya tidak memberikan perlindungan yang lengkap
- Contoh aman memori tetapi tidak di-sandbox: program Java yang dapat menimpa file melalui input pengguna
- Contoh di-sandbox tetapi tidak aman memori: program dengan hak terbatas yang ditulis dalam assembly
- Sandbox nyata juga memiliki celah struktural, seperti mengizinkan komunikasi dengan proses broker
- Karena itu, menggabungkan keamanan memori dan sandboxing adalah pendekatan pertahanan terbaik
Menggabungkan Fil-C dan sandbox OpenSSH
- Fil-C adalah implementasi aman memori untuk C/C++, yang mempertahankan keamanan pada tingkat system call Linux
- Runtime Fil-C dapat berjalan bahkan pada komponen sistem level rendah seperti
initdanudevd - OpenSSH berjalan normal di atas Fil-C dan memanfaatkan sandbox seccomp-BPF
- Runtime Fil-C dapat berjalan bahkan pada komponen sistem level rendah seperti
- Di Linux, OpenSSH membangun sandbox dengan alat berikut
chrootuntuk membatasi akses filesystem- Menjalankan proses sebagai pengguna/grup
sshd setrlimituntuk membatasi pembukaan file dan pembuatan proses- Filter seccomp-BPF untuk hanya mengizinkan system call yang diperbolehkan
- Fil-C pada dasarnya mendukung
chrootdan pergantian pengguna, tetapisetrlimitdan seccomp-BPF dapat berbenturan dengan perilaku runtime sehingga memerlukan penyesuaian tambahan
Kontrol thread pada runtime Fil-C
- Runtime Fil-C menggunakan thread latar belakang untuk garbage collection, dan akan menghentikan serta memulainya kembali secara otomatis bila diperlukan
- Sandbox
setrlimitmilik OpenSSH bertujuan melarang pembuatan proses baru, sehingga pembuatan thread oleh runtime dapat melanggar tujuan tersebut - Untuk mengatasinya, API
zlock_runtime_threads()ditambahkan ke<stdfil.h>- Runtime segera membuat thread yang dibutuhkan, lalu menonaktifkan penghentian otomatis setelahnya
- Dipanggil di fungsi
ssh_sandbox_childmilik OpenSSH sebelum pemanggilansetrlimitatau seccomp-BPF
Penyesuaian filter seccomp OpenSSH
- Setelah
zlock_runtime_threads()diterapkan, sebagian besar fitur sandbox tetap bekerja seperti semula - Perubahan berikut dilakukan pada filter seccomp
- Saat terjadi pelanggaran, diatur ke
SECCOMP_RET_KILL_PROCESSagar thread latar belakang Fil-C juga ikut dihentikan MAP_NORESERVEditambahkan ke daftar yang diizinkan untuk mendukung allocator memori Fil-C- Pemanggilan
sched_yielddiizinkan karena digunakan dalam implementasi lock milik Fil-C
- Saat terjadi pelanggaran, diatur ke
- Pemanggilan
futexuntuk sinkronisasi di Fil-C sudah diizinkan, sehingga tidak memerlukan perubahan tambahan
Cara kerja implementasi prctl di Fil-C
- Saat memasang filter seccomp, OpenSSH menggunakan dua pemanggilan
prctlPR_SET_NO_NEW_PRIVSuntuk mencegah perolehan hak tambahanPR_SET_SECCOMP, SECCOMP_MODE_FILTERuntuk mengaktifkan filter
- Masalahnya,
prctlhanya berlaku pada thread yang memanggilnya, sehingga ada risiko thread runtime Fil-C lainnya tetap tanpa filter - Untuk mencegah hal ini, Fil-C menggunakan API
filc_runtime_threads_handshake()agar penerapan dilakukan secara tersinkron ke semua thread runtime- Menjamin setiap thread melakukan pemanggilan
prctlyang sama - Jika ada beberapa thread pengguna, Fil-C memunculkan error keamanan Fil-C untuk memperkuat perlindungan
- Menjamin setiap thread melakukan pemanggilan
Kesimpulan
- Menggabungkan keamanan memori dan sandboxing adalah kombinasi keamanan yang paling kuat
- Fil-C mengintegrasikan sepenuhnya sandbox berbasis seccomp milik OpenSSH sambil tetap menjaga keamanan memori tanpa menurunkan tingkat perlindungan
- Dengan memanfaatkan Fil-C di lingkungan Linux, keamanan tingkat sistem dan keamanan tingkat bahasa dapat diperoleh secara bersamaan
1 komentar
Komentar Hacker News
Bertanya-tanya kenapa tidak ada penyebutan tentang landlock
Ada pendekatan kompilasi hibrida C → WASM → C
Dengan cara ini, interaksi dengan OS bisa dikendalikan sepenuhnya, sambil melakukan sandboxing akses memori seperti WASM, tetapi secara teknis tetap dipertahankan sebagai kode C
Materi terkait bisa dilihat di RLBox
Memori masih bisa dirusak, hanya saja cakupannya dibatasi di dalam sandbox
Sistem seperti SECCOMP bersifat birokratis karena semua kebijakan interaksi harus didefinisikan secara sangat rinci
Sebaliknya, Fil-C mengambil pendekatan di mana bahasa dan runtime-nya sendiri berusaha menjamin perilaku program yang benar
Binary Fil-C adalah executable biasa, jadi tetap bisa dipakai bersama sandbox seperti SECCOMP
Linux butuh 20 tahun untuk membuat antarmuka prctl, jadi untuk melihat hal serupa di WASI sepertinya harus menunggu sekitar 10 tahun lagi
Bahkan di dalam sandbox pun masih bisa tercipta alur eksekusi yang aneh
Penulis Fil-C memang pandai membuat penemuan yang menarik secara teknis, tetapi ada kekhawatiran apakah implementasinya sudah cukup tervalidasi
Disebutkan bahwa program setuid bisa dikompilasi dengan Fil-C, tetapi bagian yang memodifikasi ld.so bisa berisiko
Aplikasi setuid harus ditulis dengan sangat defensif terhadap variabel lingkungan, file descriptor, rlimit, sinyal, dan sebagainya
Bagian-bagian seperti ini masih belum matang, jadi ada risiko jika dipakai di infrastruktur nyata
Meski begitu, menguji codebase dengan Fil-C mungkin bisa menemukan bug yang menarik
Modifikasi ld.so hanyalah perubahan kecil untuk mengajarkan layout libc
Bug getenv terkait setuid juga sudah diperbaiki menjadi secure_getenv
Dalam kritik tadi ada sebagian kebenaran dan sebagian FUD
Dalam kondisi data race, pointer dan capability di Fil-C bisa tidak selaras
Hal ini bisa menyebabkan pelanggaran keamanan memori
Penulis menyangkalnya, tetapi membandingkannya dengan Java tidak tepat
Teknologinya hebat, tetapi sikap penulis menurunkan tingkat kepercayaan
WASM adalah sandbox sekaligus lingkungan eksekusi, dan tergantung cara penggunaannya, bisa memberi tingkat keamanan memori tertentu
Jika C dikompilasi ke WASM, bug-nya tetap ada, tetapi dampaknya menjadi terbatas
Karena itu, menggolongkan WASM sebagai teknologi sandboxing memang tepat, tetapi sebagai lingkungan eksekusi ia punya kemungkinan yang lebih luas
Bug di modul B bisa membaca data modul A
Artinya, WASM tak lebih dari pengganti sandbox proses ringan
Tentang C pun kita bisa bilang “aman tergantung cara dipakai”
WASM memang mencegah runtime escape, tetapi tidak mencegah pelarian memori di dalam program itu sendiri
Meminta perbandingan Fil-C dengan Rust
Fil-C cocok untuk memperkuat program C yang sudah ada dengan fokus pada kompatibilitas dan keamanan
Rust bagus untuk codebase baru yang membutuhkan keamanan statis dan kinerja
Fil-C punya sedikit penurunan performa, tetapi berguna untuk kode C yang sudah ada seperti ffmpeg, nginx, sudo, dan lain-lain
Rust unggul dalam multithreading dan sistem tipe
Tujuannya adalah menjamin keamanan memori, bukan memperbaiki desain bahasa
Pesaingnya lebih dekat ke D, Nim, dan Go daripada Rust
Rust mencegahnya saat compile time
Kedua pendekatan ini ortogonal, dan ke Rust pun bisa ditambahkan pemeriksaan runtime ala Fil-C
MicroVM makin populer
Menarik bagaimana Fil-C bisa memanfaatkannya
Berharap proyek ini mendapat lebih banyak perhatian
Akan bagus jika alat inti seperti sudo atau polkit bisa didistribusikan secara aman-memori
Berharap pemanfaatan sandboxing juga makin banyak di bahasa yang aman-memori
Disayangkan bahwa bahkan di Rust atau Go pun sandbox level OS jarang dipakai dengan baik
Sulit dikonfigurasi per pustaka, dan sensitif terhadap versi kernel maupun implementasi libc
Input di balik pointer seperti path file juga tidak bisa difilter, jadi ada batasannya
Karena itu, biasanya harus dikonfigurasi langsung di tingkat aplikasi
Sebaliknya, runtime Go besar sehingga sulit dibuat aman seperti Fil-C
Bertanya apa bedanya Fil-C dengan Address Sanitizer (ASan) milik clang
Jika hanya sebatas memunculkan panic saat runtime, bukankah sulit menyebutnya sebagai “aman-memori”?
Ada bug tertentu yang tidak bisa dideteksi
Karena memakai pendekatan “red zone” di sekitar memori, pendeteksian kadang bergantung pada keberuntungan
Keamanan memori bukan berarti “tidak pernah crash”, melainkan “akses yang salah tidak bisa menimbulkan efek”
Bertanya mengapa tidak memakai VM penuh sebagai sandbox
Satu proses mem-parsing input tanpa hak istimewa, sementara proses lain berjalan dengan hak lebih tinggi
Kedua proses itu berkomunikasi lewat IPC
Memakai VM memang meningkatkan keamanan, tetapi overhead-nya besar dan fitur seperti GPU atau akses file jadi rumit
Karena itu, umumnya sandbox level OS lebih rapi
GPU harus dialokasikan secara khusus, dan Qubes pun hanya terhubung lewat X11 forwarding sehingga tanpa akselerasi