Kontrol Akışı Bütünlüğü

2016 itibariyle, Android'deki tüm güvenlik açıklarının yaklaşık %86'sı bellek güvenliğiyle ilgilidir. Güvenlik açıklarının çoğu, istismar edilen uygulamanın tüm ayrıcalıklarıyla rastgele kötü niyetli faaliyetler 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 dosyanın orijinal kontrol akış grafiğinde değişiklik yapılmasına 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, medya yığınında LLVM'nin CFI uygulamasını etkinleştirdik. Android 9'da, daha fazla bileşende ve ayrıca çekirdekte CFI'yi etkinleştirdik. Sistem CFI varsayılan olarak açıktır ancak çekirdek CFI'yi etkinleştirmeniz gerekir.

LLVM'nin CFI'si , Bağlantı Zamanı Optimizasyonu (LTO) ile derlemeyi gerektirir. LTO, nesne dosyalarının LLVM bit kodu temsilini bağlantı zamanına kadar korur, bu da derleyicinin hangi optimizasyonların gerçekleştirilebileceği konusunda daha iyi akıl yürütmesine olanak tanır. LTO'nun etkinleştirilmesi, son ikili dosyanın boyutunu azaltır ve performansı artırır, ancak derleme süresini artırır. Android'de yapılan testlerde, LTO ve CFI'nin birleşimi, kod boyutu ve performansı için ihmal edilebilir ek yüke neden olur; birkaç durumda her ikisi de düzeldi.

CFI ve diğer ileri kontrol kontrollerinin nasıl yapıldığı 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 grubu için Arm64 cihazları için 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şeni makefiles/blueprint dosyasında da doğrudan etkinleştirilir.

Uygulama sistemi CFI

Clang ve Android yapı 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'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 sistemi kullanıyorsanız, makefiles veya blueprint dosyalarınıza birkaç satır ekleyerek yeni bileşenlerde CFI'yi etkinleştirebilirsiniz.

Makefile'lerde CFI'yi destekleme

/platform/frameworks/av/cmds/stagefright/Android.mk gibi bir make dosyasında CFI'yi etkinleştirmek için şunu ekleyin:

LOCAL_SANITIZE := cfi
# Optional features
LOCAL_SANITIZE_DIAG := cfi
LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt
  • LOCAL_SANITIZE oluşturma sırasında temizleyici olarak CFI'yi belirtir.
  • LOCAL_SANITIZE_DIAG CFI için teşhis modunu açar. Teşhis modu, çökmeler sırasında logcat'te yapılarınızı geliştirirken ve test ederken yararlı olan ek hata ayıklama bilgilerini yazdırır. Yine de, üretim yapılarında 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 izin verir. Bir kara listeyi, başka türlü var olabilecek, kullanıcının karşılaştığı sorunları çözmek için son çare olarak kullanabilirsiniz. Daha fazla ayrıntı için bkz. CFI'yi Devre Dışı Bırakma .

Plan dosyalarında CFI'yi destekleme

/platform/frameworks/av/media/libmedia/Android.bp gibi bir şema 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ü uyumsuzluk hataları ve derleme kodu türü uyumsuzluk hataları gibi 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 kısıtlaması nedeniyle oluşur. CFI, sanal ve sanal olmayan üye işlev çağrılarını, yalnızca aramayı yapmak için kullanılan nesnenin statik türünden 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 araçların iptal edileceği anlamına gelir. Örneğin, yığın izi 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:

Başka bir olası sorun, derlemeye dolaylı çağrılar içeren kodda CFI'yi 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 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 şubeler CFI tarafından araçlandırılmadığından (çalışma zamanında yeniden görevlendirilemezler ve bu nedenle bir güvenlik riski oluşturmazlar), bu sorunu çözecektir.

Çok fazla derleme işlevi varsa ve bunların tümü düzeltilemezse, dolaylı derleme çağrıları içeren tüm işlevleri de kara listeye alabilirsiniz. Bu işlevler üzerindeki CFI kontrollerini devre dışı bıraktığı ve böylece saldırı yüzeyini açtığı için bu önerilmez.

CFI'yi devre dışı bırakma

Herhangi bir performans yükü gözlemlemedik, bu nedenle CFI'yi devre dışı bırakmanız gerekmez. Bununla birlikte, kullanıcıya yönelik bir etki varsa, derleme zamanı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 araçlarını devre dışı bırakması talimatını verir.

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ümantasyonu almayacak bireysel işlevleri seçmenize izin verir). Bir kara liste dosyasının formatı hakkında daha fazla ayrıntı için yukarı akış Clang belgelerine bakın.

Doğrulama

Şu anda, CFI'ye özel bir CTS testi bulunmamaktadır. Bunun yerine, CFI'nin cihazı etkilemediğini doğrulamak için CTS testlerinin CFI etkinken veya etkin olmadan geçtiğinden emin olun.