- Bellek güvenliği ve sandboxing, birbirinden bağımsız güvenlik kavramlarıdır; güçlü bir savunma yapısı oluşturmak için her ikisinin de birlikte bulunması gerekir
- Fil-C, C/C++ için bellek güvenli bir uygulamadır; Linux sistem çağrısı seviyesine kadar güvenliği garanti eder ve OpenSSH gibi sistem bileşenlerinde de kullanılabilir
- OpenSSH'in seccomp-BPF tabanlı sandbox yapısını Fil-C'ye taşırken, iş parçacığı oluşturma kısıtları ve seccomp filtresinin ayarlanması temel zorluklardı
- Fil-C çalışma zamanının arka plan iş parçacığı yönetimi için
zlock_runtime_threads() API'si eklendi; bu API sandbox içinde iş parçacığı davranışını denetler
- Fil-C,
prctl çağrılarını tüm çalışma zamanı iş parçacıklarına senkronize şekilde uygulayarak no_new_privs ve seccomp filtresinin tüm süreç genelinde tutarlı biçimde uygulanmasını sağlar
Bellek güvenliği ve sandboxing ilişkisi
- Bellek güvenliği ve sandboxing, farklı güvenlik katmanlarıdır; yalnızca biri tek başına tam koruma sağlamaz
- Bellek güvenli ama sandbox içinde olmayan örnek: Kullanıcı girdisi üzerinden dosyaların üzerine yazabilen bir Java programı
- Sandbox içinde ama bellek güvenli olmayan örnek: Yetkileri kısıtlanmış, assembly ile yazılmış bir program
- Gerçek dünyadaki sandbox'larda, broker süreciyle iletişime izin verilmesi gibi yapısal açıklar bulunur
- Bu nedenle en iyi savunma yaklaşımı, bellek güvenliği ile sandboxing'i birlikte kullanmaktır
Fil-C ile OpenSSH sandbox'ının birleştirilmesi
- Fil-C, C/C++ için bellek güvenli bir uygulamadır ve Linux sistem çağrısı seviyesinde güvenliği korur
- Fil-C çalışma zamanı,
init, udevd gibi düşük seviyeli sistem bileşenlerinde de çalışabilir
- OpenSSH, Fil-C üzerinde sorunsuz çalışır ve seccomp-BPF sandbox yapısını kullanır
- OpenSSH, Linux'ta sandbox'ı şu araçlarla kurar
chroot ile dosya sistemi erişimini kısıtlama
sshd kullanıcısı/grubu olarak çalıştırma
setrlimit ile dosya açma ve süreç oluşturma sınırları koyma
- seccomp-BPF filtresi ile yalnızca izin verilen sistem çağrılarına izin verme
- Fil-C,
chroot ve kullanıcı değiştirmeyi varsayılan olarak destekler; ancak setrlimit ve seccomp-BPF, çalışma zamanı davranışıyla çakışabileceği için ek ayarlamalar gerekir
Fil-C çalışma zamanında iş parçacığı denetimi
- Fil-C çalışma zamanı, çöp toplama için arka plan iş parçacıkları kullanır; gerektiğinde bunları otomatik olarak durdurup yeniden başlatabilir
- OpenSSH'in
setrlimit sandbox'ı, yeni süreç oluşturmayı engellemeyi hedeflediğinden, çalışma zamanının iş parçacığı oluşturması bununla çelişebilir
- Bunu çözmek için
<stdfil.h> içine zlock_runtime_threads() API'si eklendi
- Çalışma zamanı, ihtiyaç duyduğu iş parçacıklarını hemen oluşturur ve sonrasında otomatik sonlandırmayı devre dışı bırakır
- Bu çağrı, OpenSSH'in
ssh_sandbox_child fonksiyonunda setrlimit veya seccomp-BPF çağrılarından önce yapılır
OpenSSH seccomp filtresinin ayarlanması
zlock_runtime_threads() uygulandıktan sonra sandbox işlevlerinin çoğu olduğu gibi çalışmaya devam etti
- seccomp filtresinde şu değişiklikler yapıldı
- İhlal durumunda
SECCOMP_RET_KILL_PROCESS ayarlanarak Fil-C arka plan iş parçacıklarının da birlikte sonlandırılması sağlandı
MAP_NORESERVE, Fil-C bellek ayırıcısını desteklemek için izin listesine eklendi
sched_yield çağrısına izin verildi; Fil-C'nin kilit uygulamasında kullanılır
- Fil-C'nin eşzamanlama için kullandığı
futex çağrıları zaten izinli olduğundan ek değişiklik gerekmedi
Fil-C'nin prctl uygulama yöntemi
- OpenSSH, seccomp filtresini kurarken iki tür
prctl çağrısı kullanır
PR_SET_NO_NEW_PRIVS ile ek ayrıcalık kazanımını engelleme
PR_SET_SECCOMP, SECCOMP_MODE_FILTER ile filtreyi etkinleştirme
- Sorun şu ki
prctl, yalnızca çağrıyı yapan iş parçacığına uygulanır; bu da Fil-C'nin diğer çalışma zamanı iş parçacıklarının filtresiz kalma riskini doğurur
- Fil-C bunu önlemek için
filc_runtime_threads_handshake() API'si ile tüm çalışma zamanı iş parçacıklarına senkronize uygulama yapar
- Her iş parçacığının aynı
prctl çağrısını gerçekleştirmesini garanti eder
- Birden fazla kullanıcı iş parçacığı varsa Fil-C güvenlik hatası oluşturarak korumayı güçlendirir
Sonuç
- Bellek güvenliği ile sandboxing'in birleşimi, en güçlü güvenlik kombinasyonudur
- Fil-C, OpenSSH'in seccomp tabanlı sandbox'ını tamamen entegre ederken koruma seviyesini düşürmeden bellek güvenliğini korur
- Linux ortamında Fil-C kullanıldığında, sistem seviyesi güvenlik ile dil seviyesi güvenlik aynı anda elde edilebilir
1 yorum
Hacker News görüşleri
Neden landlock’tan hiç bahsedilmediğini merak ediyor
C → WASM → C şeklinde ilerleyen bir hibrit derleme yaklaşımı var
Bu sayede OS etkileşimleri tamamen kontrol edilebiliyor ve WASM gibi bellek erişimi sandbox içine alınırken teknik olarak hâlâ C kodu olarak kalıyor
İlgili materyaller RLBox üzerinde görülebilir
Belleği bozabilir, ama bunun kapsamı sandbox’ın içiyle sınırlı kalır
SECCOMP gibi sistemler tüm etkileşim politikalarının ayrıntılı biçimde tanımlanmasını gerektirdiği için bürokratik kalır
Buna karşılık Fil-C, dilin ve runtime’ın kendisinin programın doğru çalışmasını garanti etmeye çalıştığı bir yaklaşım izliyor
Fil-C binary’leri normal yürütülebilir dosyalar olduğundan SECCOMP gibi sandbox’larla birlikte de kullanılabilir
Linux’un prctl arayüzünü oluşturması 20 yıl sürdüyse, WASI’de benzer bir şey görmek için herhalde 10 yıl beklemek gerekecek
Sandbox’ın içinde bile tuhaf yürütme akışları oluşturulabilir
Fil-C’nin yazarı teknik olarak ilginç icatlar yapıyor, ancak uygulamanın yeterince doğrulanıp doğrulanmadığı konusunda endişe var
setuid programlarının Fil-C ile derlenebileceği söylenmişti, ancak
ld.soüzerinde yapılan değişiklikler riskli olabilirsetuid uygulamalarının ortam değişkenleri, dosya tanımlayıcıları,
rlimit, sinyaller vb. konularda çok savunmacı yazılması gerekirBu kısımlar henüz tamamlanmamış göründüğünden gerçek altyapıda kullanmak riskli olabilir
Yine de bir kod tabanını Fil-C ile test etmek ilginç hataları ortaya çıkarabilir
ld.sodeğişikliği, libc düzenini öğretmek düzeyinde küçük bir değişikliksetuid ile ilgili
getenvhatası da zatensecure_getenvile düzeltilmişSöylenenlerde biraz gerçek, biraz da FUD var
Fil-C’de veri yarışı durumlarında pointer ile capability uyumsuz hâle gelebilir
Bu da bellek güvenliği ihlallerine yol açabilir
Yazar bunu reddediyor, ama Java ile karşılaştırmak uygun değil
Teknoloji harika olsa da yazarın tavrı güveni azaltıyor
WASM, bir sandbox ve bir çalışma ortamı olarak, kullanım biçimine bağlı olarak belli ölçüde bellek güvenliği sağlayabilir
C’yi WASM’a derleyince hatalar hâlâ var olur, ama etkilerinin kapsamı sınırlanır
Bu yüzden WASM’ı bir sandbox teknolojisi olarak sınıflandırmak doğru, ancak çalışma ortamı olarak daha fazla olasılık sunuyor
B modülündeki bir hata yüzünden A modülünün verileri okunabilir
Yani WASM, hafif process sandbox’larının yerini alan bir şeyden ibaret
Sonuçta C için de “nasıl kullandığına bağlı olarak güvenlidir” denebilir
WASM runtime’dan kaçışı engeller ama içerdeki programın bellekten kaçmasını engelleyemez
Fil-C ile Rust karşılaştırması isteniyor
Fil-C mevcut C programlarını uyumluluk ve güvenlik odaklı olarak güçlendirmek için uygun
Rust ise yeni kod tabanları oluştururken statik güvenlik ve performans sağlamak için daha iyi
Fil-C biraz performans kaybı yaşatıyor ama mevcut C kodlarında (
ffmpeg,nginx,sudovb.) faydalıRust’ın güçlü yanı multithreading ve type system
Amaç dil tasarımını iyileştirmekten çok bellek güvenliğini sağlamak
Rakipleri Rust’tan ziyade D, Nim ve Go’ya daha yakın
Rust ise bunu derleme zamanında önler
İki yaklaşım birbirine dik ve Rust’a da Fil-C tarzı runtime kontrolleri eklenebilir
MicroVM giderek daha popüler oluyor
Fil-C’nin bunu nasıl kullanabileceği merak ediliyor
Bu projenin daha fazla ilgi görmesi isteniyor
sudo veya polkit gibi temel araçların bellek güvenli biçimde dağıtılması güzel olurdu
Bellek güvenli dillerde bile sandbox kullanımının artması isteniyor
Rust veya Go’da da OS düzeyindeki sandbox’ların pek kullanılmaması üzücü
Library düzeyinde yapılandırması zor ve kernel sürümüne ya da libc uygulamasına duyarlı
Dosya yolu gibi pointer arkasındaki girdileri filtreleyemediği için sınırlı kalıyor
Bu nedenle genelde doğrudan uygulama düzeyinde ayarlanması gerekiyor
Buna karşılık Go’nun runtime’ı büyük olduğundan Fil-C’deki gibi güvenli hâle getirmek zor
Fil-C’nin clang’in Address Sanitizer’ından (ASan) farkının ne olduğu merak ediliyor
Sadece runtime panic üretmekten ibaretse buna “bellek güvenli” demenin zor olduğu söyleniyor
Bazı hataları tespit edemez
Belleğin etrafına “red zone” koyma yaklaşımını kullandığı için ancak şans varsa algılanır
Bellek güvenliği “çökmemek” değil, “yanlış erişimin etkili olamaması” anlamına gelir
Neden tam bir VM’in sandbox olarak kullanılmaması gerektiği soruluyor
Bir process yetkisiz biçimde girdiyi ayrıştırır, diğer process ise yüksek yetkiyle çalışır
Bu iki process IPC ile haberleşir
VM kullanmak güvenliği artırır, ama overhead yüksektir ve GPU ya da dosya erişimi gibi işlevler karmaşıklaşır
Bu yüzden genel olarak OS düzeyinde sandboxing daha temiz bir çözümdür
GPU’yu özel olarak atamak gerekir ve Qubes da yalnızca X11 forwarding ile bağlandığından hızlandırma yoktur