2016 itibarıyla Android'deki tüm güvenlik açıklarının yaklaşık% 86'sı bellek güvenliğiyle ilgilidir. Çoğu güvenlik açığı, saldırganlar tarafından bir uygulamanın normal kontrol akışını değiştirerek, güvenlik açığı bulunan uygulamanın tüm ayrıcalıklarıyla rastgele kötü amaçlı etkinlikler gerçekleştirmek için kullanılır. Kontrol akışı bütünlüğü (CFI), derlenmiş bir ikilinin orijinal kontrol akışı grafiğinde değişiklik yapılmasına izin vermeyen bir güvenlik mekanizmasıdır. Bu mekanizma, bu tür saldırıları gerçekleştirmeyi önemli ölçüde zorlaştırır.
Android 8.1'de, medya yığınında LLVM'nin CFI uygulamasını etkinleştirdik. Android 9'da CFI'yi daha fazla bileşende ve çekirdekte etkinleştirdik. Sistem CFI varsayılan olarak etkindir ancak çekirdek CFI'yı etkinleştirmeniz gerekir.
LLVM'nin CFI'si, bağlantı zamanı optimizasyonu (LTO) ile derlemeyi gerektirir. LTO, nesne dosyalarının LLVM bit kodu gösterimini bağlantı zamanına kadar korur. Bu sayede derleyici, hangi optimizasyonların yapılabileceği konusunda daha iyi bir şekilde akıl yürütebilir. LTO'nun etkinleştirilmesi, nihai ikilinin boyutunu küçültür ve performansı artırır ancak derleme süresini uzatır. Android'de yapılan testlerde LTO ve CFI kombinasyonu, kod boyutu ve performans açısından ihmal edilebilir bir ek yükle sonuçlanır. Bazı durumlarda her ikisi de iyileşir.
CFI ve diğer ileri kontrol kontrollerinin işlenmesiyle ilgili daha fazla teknik bilgi için LLVM tasarım belgelerine bakın.
Örnekler ve kaynak
CFI, derleyici tarafından sağlanır ve derleme sırasında ikili dosyaya enstrümantasyon ekler. Clang araç zincirinde ve AOSP'deki Android derleme sisteminde CFI'yi destekliyoruz.
CFI, /platform/build/target/product/cfi-common.mk
içindeki bileşenler için Arm64 cihazlarda varsayılan olarak etkindir.
Ayrıca, /platform/frameworks/av/media/libmedia/Android.bp
ve /platform/frameworks/av/cmds/stagefright/Android.mk
gibi bir dizi medya bileşeninin makefile/blueprint dosyalarında doğrudan etkinleştirilir.
Sistem CFI'sını uygulama
Clang ve Android derleme sistemini kullanıyorsanız CFI varsayılan olarak etkindir. CFI, Android kullanıcılarının güvenliğini sağlamaya yardımcı olduğundan devre dışı bırakılmamalıdır.
Hatta ek bileşenler için CFI'yi etkinleştirmenizi önemle tavsiye ederiz. İdeal adaylar, ayrıcalıklı yerel kod veya güvenilmeyen kullanıcı girişini işleyen yerel koddur. Clang ve Android derleme sistemini kullanıyorsanız makefile'larınıza veya blueprint dosyalarınıza birkaç satır ekleyerek yeni bileşenlerde CFI'yı etkinleştirebilirsiniz.
Makefile'larda CFI'yi destekleme
/platform/frameworks/av/cmds/stagefright/Android.mk
gibi bir make dosyasında CFI'yı etkinleştirmek için şunu ekleyin:
LOCAL_SANITIZE := cfi # Optional features LOCAL_SANITIZE_DIAG := cfi LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt
LOCAL_SANITIZE
, derleme sırasında temizleyici olarak CFI'yı belirtir.LOCAL_SANITIZE_DIAG
, CFI için teşhis modunu etkinleştirir. Teşhis modu, kilitlenme sırasında logcat'te ek hata ayıklama bilgileri yazdırır. Bu bilgiler, derlemelerinizi geliştirirken ve test ederken faydalıdır. Ancak üretim derlemelerinde teşhis modunu kaldırdığınızdan emin olun.LOCAL_SANITIZE_BLACKLIST
, bileşenlerin tek tek işlevler veya kaynak dosyalar için CFI enstrümanını seçerek devre dışı bırakmasına olanak tanır. Kullanıcıların karşılaşabileceği sorunları düzeltmek için son çare olarak kara liste kullanabilirsiniz. Daha fazla bilgi için CFI'yı devre dışı bırakma başlıklı makaleyi inceleyin.
Plan dosyalarında CFI'yi destekleme
/platform/frameworks/av/media/libmedia/Android.bp
gibi bir plan dosyasında CFI'yi etkinleştirmek için şunu ekleyin:
sanitize: { cfi: true, diag: { cfi: true, }, blacklist: "cfi_blacklist.txt", },
Sorun giderme
Yeni bileşenlerde CFI'yi etkinleştiriyorsanız işlev türü uyuşmazlığı hataları ve derleme kodu türü uyuşmazlığı hataları ile ilgili bazı sorunlarla karşılaşabilirsiniz.
İşlev türü uyuşmazlığı hataları, CFI'ın dolaylı çağrıları yalnızca çağrıda kullanılan statik türle aynı dinamik türe sahip işlevlere atlamayla kısıtlamasından kaynaklanır. CFI, sanal ve sanal olmayan üye işlevi çağrılarını yalnızca çağrı yapmak için kullanılan nesnenin statik türünün türetilmiş bir sınıfı olan nesnelere atlamayla kısıtlar. Bu nedenle, bu varsayımlardan birini ihlal eden kodunuz olduğunda CFI'ın eklediği enstrüman oluşturma işlemi iptal edilir. Örneğin, yığın izlemede SIGABRT gösteriliyor ve logcat'te kontrol akışı bütünlüğünün uyuşmazlık bulduğuyla ilgili bir satır yer alıyor.
Bu sorunu düzeltmek için çağrılan işlevin, statik olarak bildirilen türle aynı türe sahip olduğundan emin olun. Aşağıda iki örnek CL verilmiştir:
- Bluetooth: /c/platform/system/bt/+/532377
- NFC: /c/platform/system/nfc/+/527858
Diğer olası sorun ise derlemeye dolaylı çağrılar içeren kodda CFI'yı etkinleştirmeye çalışmaktır. Derleme kodu yazılmadığı için tür uyuşmazlığı oluşur.
Bu sorunu düzeltmek için her montaj çağrısı için yerel kod sarmalayıcıları oluşturun ve sarmalayıcılara, çağıran işaretçiyle aynı işlev imzasını verin. Sarmalayıcı daha sonra doğrudan derleme kodunu çağırabilir. Doğrudan dallar CFI tarafından izlenmediğinden (çalışma zamanında yeniden yönlendirilemezler ve bu nedenle güvenlik riski oluşturmazlar) bu işlem sorunu düzeltecektir.
Çok fazla montaj işlevi varsa ve bunların tümü düzeltilemiyorsa montaja dolaylı çağrı içeren tüm işlevleri kara listeye de alabilirsiniz. Bu, söz konusu işlevlerde CFI kontrollerini devre dışı bırakarak saldırı yüzeyini açtığı için önerilmez.
CFI'yı devre dışı bırakma
Herhangi bir performans ek yükü gözlemlemediğimiz için CFI'yı devre dışı bırakmanız gerekmez. Ancak kullanıcıya yönelik bir etki varsa derleme sırasında temizleyici kara liste dosyası sağlayarak CFI'yi tek tek işlevler veya kaynak dosyalar için seçmeli olarak devre dışı bırakabilirsiniz. Kara liste, derleyiciye belirtilen konumlarda CFI enstrümantasyonunu devre dışı bırakmasını söyler.
Android derleme sistemi, hem Make hem de Soong için bileşen başına kara listeleri destekler (CFI enstrümantasyonu almayacak kaynak dosyaları veya tek tek işlevleri seçmenize olanak tanır). Kara liste dosyasının biçimi hakkında daha fazla bilgi için yukarı akış Clang belgelerine bakın.
Doğrulama
Şu anda CFI için özel olarak tasarlanmış bir CTS testi yoktur. Bunun yerine, CFI'nın cihazı etkilemediğini doğrulamak için CTS testlerinin CFI etkin veya devre dışı olarak geçtiğinden emin olun.