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çığından, saldırganlar tarafından bir uygulamanın normal kontrol akışını değiştirerek yararlanılır. Bu sayede, istismar edilen uygulamanın tüm ayrıcalıklarıyla keyfi kötü amaçlı etkinlikler gerçekleştirilebilir. Kontrol akışı bütünlüğü (CFI), derlenmiş bir ikili dosyanın orijinal kontrol akışı grafiğinde değişiklik yapılmasına izin vermeyen bir güvenlik mekanizmasıdır. Bu sayede, bu tür saldırıların yapılması önemli ölçüde zorlaştırılır.
Android 8.1'de, LLVM'in medya yığınında CFI uygulamasını etkinleştirdik. Android 9'da CFI'yi daha fazla bileşende ve çekirdekte etkinleştirdik. Sistem CFI varsayılan olarak açıktır ancak çekirdek CFI'yi etkinleştirmeniz gerekir.
LLVM'nin CFI özelliği, Bağlantı Sırasında Optimizasyon (LTO) ile derlemeyi gerektirir. LTO, bağlayıcı zamanına kadar nesne dosyalarının LLVM bit kodu temsilini korur. Bu sayede derleyici, hangi optimizasyonların yapılabileceği konusunda daha iyi bir fikir edinebilir. LTO'yu etkinleştirmek nihai ikili dosyanın boyutunu azaltır ve performansı artırır ancak derleme süresini uzatır. Android'de yapılan testlerde, LTO ve CFI'nin birlikte kullanılması, kod boyutu ve performansında önemsiz bir ek yüke neden olur. Bazı durumlarda her ikisi de iyileşir.
CFI ve diğer ileri kontrol denetimlerinin nasıl ele alındığıyla ilgili daha fazla teknik bilgi için LLVM tasarım dokümanlarına 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'teki Android derleme sisteminde CFI'yi destekliyoruz.
CFI, /platform/build/target/product/cfi-common.mk
'teki bileşen grubu 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'yi 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'lerinize veya plan dosyalarınıza birkaç satır ekleyerek yeni bileşenlerde CFI'yi etkinleştirebilirsiniz.
Makefile'lerde CFI desteği
/platform/frameworks/av/cmds/stagefright/Android.mk
gibi bir make dosyasında CFI'yi etkinleştirmek için şunları ekleyin:
LOCAL_SANITIZE := cfi # Optional features LOCAL_SANITIZE_DIAG := cfi LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt
LOCAL_SANITIZE
, derleme sırasında CFI'yi temizleyici olarak belirtir.LOCAL_SANITIZE_DIAG
, CFI için teşhis modunu etkinleştirir. Teşhis modu, kilitlenmeler sırasında logcat'te ek hata ayıklama bilgileri yazdırır. Bu bilgiler, derlemelerinizi geliştirip test ederken faydalıdır. Bununla birlikte, ü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ümantasyonunu seçerek devre dışı bırakmasına olanak tanır. Kullanıcılara yönelik olabilecek sorunları düzeltmek için son çare olarak kara listeyi kullanabilirsiniz. Daha fazla bilgi için CFI'yi devre dışı bırakma başlıklı makaleyi inceleyin.
Taslak dosyalarında CFI desteği
/platform/frameworks/av/media/libmedia/Android.bp
gibi bir taslak dosyasında CFI'yi etkinleştirmek için şunları 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ıyla ve derleme kodu türü uyuşmazlığı hatalarıyla karşılaşabilirsiniz.
İşlev türü uyuşmazlığı hataları, CFI'nin dolaylı çağrıları yalnızca çağrıda kullanılan statik türle aynı dinamik türe sahip işlevlere atlamakla sınırlandırdığı için ortaya çıkar. 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ş sınıfı olan nesnelere atlayacak şekilde kısıtlar. Bu, bu varsayımlardan herhangi birini ihlal eden bir kodunuz olduğunda CFI'nin eklediği enstrümantasyonun iptal edileceği anlamına gelir. Örneğin, yığın izlemede SIGABRT gösterilir ve logcat'te, kontrol akışı bütünlüğünün uyuşmazlık bulduğuyla ilgili bir satır bulunur.
Bu sorunu düzeltmek için çağrılan işlevin statik olarak tanımlanan işlevle aynı türde olduğundan emin olun. Aşağıda iki örnek CL verilmiştir:
- Bluetooth: /c/platform/system/bt/+/532377
- NFC: /c/platform/system/nfc/+/527858
Olası bir diğer sorun da, derleme diline dolaylı çağrılar içeren kodda CFI'yi etkinleştirmeye çalışmaktır. Derleme kodu yazılmadığı için bu durum tür uyuşmazlığına neden olur.
Bu sorunu düzeltmek için her bir derleme ç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 donatılmadığı için (çalışma zamanında yeniden yönlendirilemezler ve bu nedenle güvenlik riski oluşturmazlar) bu işlem sorunu çözecektir.
Çok fazla derleme işlevi varsa ve bunların tümü düzeltilemezse derlemeye dolaylı çağrılar içeren tüm işlevleri de kara listeye ekleyebilirsiniz. Bu işlevlerde CFI kontrollerini devre dışı bırakarak saldırı yüzeyini açtığı için bu yöntem önerilmez.
CFI'yi devre dışı bırakma
Performans yükü gözlemlemediğimiz için CFI'yi devre dışı bırakmanız gerekmez. Ancak kullanıcılara yönelik bir etki varsa derleme sırasında bir temizleyici kara liste dosyası sağlayarak CFI'yi tek tek işlevler veya kaynak dosyalar için seçerek 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 listeler için destek sağlar (CFI enstrümantasyonu almayacak kaynak dosyaları veya ayrı 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 bir CTS testi yoktur. Bunun yerine, CFI'nin cihazı etkilemediğini doğrulamak için CTS testlerinin CFI etkin veya devre dışıyken geçtiğinden emin olun.