2016 itibariyle, Android'deki tüm güvenlik açıklarının yaklaşık %86'sı bellek güvenliğiyle ilgilidir. Çoğu güvenlik açığı, istismar edilen uygulamanın tüm ayrıcalıklarıyla rastgele kötü amaçlı etkinlikler gerçekleştirmek için bir uygulamanın normal kontrol akışını değiştiren saldırganlar tarafından kullanılır. Kontrol akışı bütünlüğü (CFI), derlenmiş bir ikili programın orijinal kontrol akış grafiğinde değişikliklere izin vermeyen ve bu tür saldırıların gerçekleştirilmesini önemli ölçüde zorlaştıran bir güvenlik mekanizmasıdır.
Android 8.1'de, LLVM'nin medya yığınında CFI uygulamasını etkinleştirdik. Android 9'da, daha fazla bileşende ve ayrıca çekirdekte CFI'yı etkinleştirdik. Sistem CFI varsayılan olarak açıktır ancak çekirdek CFI'yı etkinleştirmeniz gerekir.
LLVM'nin CFI'sı, 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 da derleyicinin hangi optimizasyonların gerçekleştirilebileceği hakkında daha iyi nedenler bulmasını sağlar. LTO'nun etkinleştirilmesi, son ikili dosyanın boyutunu küçültür ve performansı artırır, ancak derleme süresini artırır. Android üzerinde yapılan testlerde, LTO ve CFI kombinasyonu, kod boyutu ve performansı açısından ihmal edilebilir bir ek yüke neden olur; birkaç durumda her ikisi de düzeldi.
CFI ve diğer ileri kontrol kontrollerinin nasıl işlendiği hakkında daha fazla teknik ayrıntı için LLVM tasarım belgelerine bakın.
Örnekler ve kaynak
CFI, derleyici tarafından sağlanır ve derleme süresi boyunca ikili dosyaya enstrümantasyon ekler. Clang araç zincirinde CFI'yi ve AOSP'de Android derleme sistemini destekliyoruz.
CFI, /platform/build/target/product/cfi-common.mk içindeki bileşen kümesi için /platform/build/target/product/cfi-common.mk
aygıtları için varsayılan olarak etkinleştirilmiştir. Ayrıca, /platform/frameworks/av/media/libmedia/Android.bp
ve /platform/frameworks/av/cmds/stagefright/Android.mk
gibi bir dizi medya bileşeninin makefiles/blueprint dosyasında doğrudan etkinleştirilir.
Uygulama sistemi CFI
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, onu devre dışı bırakmamalısınız.
Aslında, ek bileşenler için CFI'yı etkinleştirmenizi şiddetle tavsiye ederiz. İdeal adaylar, ayrıcalıklı yerel kod veya güvenilmeyen kullanıcı girişini işleyen yerel koddur. Clang ve Android derleme sistemi kullanıyorsanız, makefiles veya blueprint dosyalarınıza birkaç satır ekleyerek CFI'yi yeni bileşenlerde etkinleştirebilirsiniz.
Makefiles'de CFI'yi destekleme
/platform/frameworks/av/cmds/stagefright/Android.mk gibi bir make dosyasında /platform/frameworks/av/cmds/stagefright/Android.mk
etkinleştirmek için şunu ekleyin:
LOCAL_SANITIZE := cfi # Optional features LOCAL_SANITIZE_DIAG := cfi LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt
-
LOCAL_SANITIZE
, yapı sırasında dezenfektan olarak CFI'yi belirtir. -
LOCAL_SANITIZE_DIAG
, CFI için tanı modunu açar. Tanılama modu, yapılarınızı geliştirirken ve test ederken yararlı olan, çökmeler sırasında logcat'te ek hata ayıklama bilgilerini yazdırır. Yine de, üretim yapılarında tanı modunu kaldırdığınızdan emin olun. -
LOCAL_SANITIZE_BLACKLIST
, bileşenlerin bireysel işlevler veya kaynak dosyalar için CFI enstrümantasyonunu seçici olarak devre dışı bırakmasına izin verir. Aksi takdirde var olabilecek, kullanıcıyla ilgili sorunları gidermek için son çare olarak bir kara liste kullanabilirsiniz. Daha fazla ayrıntı için bkz. CFI'yı Devre Dışı Bırakma .
Plan dosyalarında CFI'yi destekleme
/platform/frameworks/av/media/libmedia/Android.bp gibi bir plan dosyasında /platform/frameworks/av/media/libmedia/Android.bp
etkinleştirmek için şunu ekleyin:
sanitize: { cfi: true, diag: { cfi: true, }, blacklist: "cfi_blacklist.txt", },
Sorun giderme
Yeni bileşenlerde CFI'yı etkinleştiriyorsanız, işlev türü uyumsuzluk hataları ve montaj kodu türü uyumsuzluk hatalarıyla ilgili birkaç sorunla 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 atlayacak şekilde sınırlandırması nedeniyle oluşur. CFI, sanal ve sanal olmayan üye işlev çağrılarını yalnızca çağrıyı yapmak için kullanılan nesnenin statik türünün türetilmiş bir sınıfı olan nesnelere atlayacak şekilde kısıtlar. Bu, bu varsayımlardan herhangi birini ihlal eden kodunuz olduğunda, CFI'nin eklediği enstrümantasyonun iptal edileceği anlamına gelir. Örneğin, yığın izlemesi bir SIGABRT gösterir ve logcat, bir uyumsuzluk bulan kontrol akışı bütünlüğü hakkında bir satır içerir.
Bunu düzeltmek için, çağrılan işlevin statik olarak bildirilenle aynı türe sahip olduğundan emin olun. İşte iki örnek CL:
- Bluetooth : /c/platform/sistem/bt/+/532377
- NFC : /c/platform/sistem/nfc/+/527858
Başka bir olası sorun, derlemeye dolaylı çağrılar içeren kodda CFI'yı etkinleştirmeye çalışmaktır. Derleme kodu yazılmadığından, bu bir tür uyuşmazlığına neden olur.
Bunu 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. Sarıcı daha sonra doğrudan montaj kodunu arayabilir. Doğrudan şubeler CFI tarafından donatılmadığından (çalışma zamanında yeniden atanamazlar ve bu nedenle bir güvenlik riski oluşturmazlar), bu sorunu çözecektir.
Çok fazla derleme işlevi varsa ve bunların tümü düzeltilemiyorsa, derlemeye dolaylı çağrılar içeren tüm işlevleri de kara listeye alabilirsiniz. Bu işlevler üzerindeki CFI denetimlerini devre dışı bıraktığı ve böylece saldırı yüzeyini açtığı için bu önerilmez.
CFI'yı devre dışı bırakma
Herhangi bir performans yükü gözlemlemedik, bu nedenle CFI'yı devre dışı bırakmanız gerekmez. Ancak, kullanıcıya yönelik bir etki varsa, derleme zamanında bir dezenfektan kara liste dosyası sağlayarak CFI'yı bireysel 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 (kaynak dosyaları veya CFI enstrümantasyonunu almayacak bireysel işlevleri seçmenize olanak tanır). Kara liste dosyasının biçimi hakkında daha fazla ayrıntı için yukarı akış Clang belgelerine bakın.
doğrulama
Şu anda, özellikle CFI için bir CTS testi bulunmamaktadır. Bunun yerine, CFI'nin cihazı etkilemediğini doğrulamak için CFI etkinken veya CFI olmadan CTS testlerinin geçtiğinden emin olun.