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

2016 yılı 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çığı, bir uygulamanın normal kontrol akışını, istismar edilen uygulamanın tüm ayrıcalıklarıyla keyfi kötü amaçlı etkinlikler gerçekleştirmek üzere değiştiren saldırganlar tarafından istismar edilir. Kontrol akışı bütünlüğü (CFI), derlenmiş bir ikili programı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 LLVM'nin medya yığınında CFI uygulamasını etkinleştirdik. Android 9'da CFI'yı daha fazla bileşende ve ayrıca çekirdekte etkinleştirdik. Sistem CFI varsayılan olarak açıktır ancak çekirdek CFI'yi etkinleştirmeniz gerekir.

LLVM'nin CFI'si Bağlantı Süresi Optimizasyonu (LTO) ile derlenmeyi gerektirir. LTO, nesne dosyalarının LLVM bit kodu gösterimini bağlantı zamanına kadar korur; bu, derleyicinin hangi optimizasyonların gerçekleştirilebileceği konusunda daha iyi karar vermesine 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 üzerinde yapılan testlerde, LTO ve CFI kombinasyonu, kod boyutu ve performansı açısından ihmal edilebilir düzeyde ek yüke neden olur; birkaç vakada her ikisi de iyileşti.

CFI ve diğer ileri kontrol kontrollerinin nasıl ele alındığı 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 Arm64 aygıtları 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şeninin makefiles/blueprint dosyalarında da doğrudan etkinleştirilir.

Sistem CFI'sinin uygulanması

Clang ve Android derleme sistemini kullanıyorsanız CFI varsayılan olarak etkindir. CFI, Android kullanıcılarının güvende kalmasına yardımcı olduğundan onu devre dışı bırakmamalısınız.

Aslında ek bileşenler için CFI'yi 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 sistemini kullanıyorsanız, makefile veya blueprint dosyalarınıza birkaç satır ekleyerek CFI'yi yeni bileşenlerde etkinleştirebilirsiniz.

Makefile'larda 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. Tanılama modu, çökmeler sırasında logcat'te ek hata ayıklama bilgilerini yazdırır; bu, yapılarınızı geliştirirken ve test ederken faydalıdır. Yine de üretim yapılarında tanılama modunu kaldırdığınızdan emin olun.
  • LOCAL_SANITIZE_BLACKLIST bileşenlerin ayrı ayrı işlevler veya kaynak dosyalar için CFI enstrümantasyonunu seçici olarak devre dışı bırakmasına olanak tanır. Kullanıcının karşılaşabileceği sorunları çözmek için son çare olarak kara listeyi 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 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ü uyumsuzluğu hataları ve montaj kodu türü uyumsuzluğu hataları ile ilgili birkaç sorunla karşılaşabilirsiniz.

İşlev türü uyumsuzluğu 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 ç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 bir kodunuz olduğunda, CFI'nin eklediği enstrümantasyonun iptal edileceği anlamına gelir. Örneğin, yığın izlemesi bir SIGABRT'yi 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 bildirilen türde olduğundan emin olun. İşte iki örnek CL:

Bir başka olası sorun da derlemeye dolaylı çağrılar içeren kodda CFI'yi etkinleştirmeye çalışmaktır. Montaj kodu yazılmadığından 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. Paketleyici daha sonra doğrudan montaj kodunu çağırabilir. Doğrudan şubeler CFI tarafından denetlenmediğinden (çalışma zamanında yeniden işaretlenemezler ve dolayısıyla bir güvenlik riski oluşturmazlar), bu durum 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şlevlerdeki CFI denetimlerini devre dışı bırakıp saldırı yüzeyini açtığı için bu önerilmez.

CFI'yi devre dışı bırakma

Herhangi bir performans yükü gözlemlemedik, dolayısıyla CFI'yi devre dışı bırakmanıza gerek yok. Bununla birlikte, kullanıcının karşılaştığı bir etki varsa, derleme zamanında bir temizleyici kara liste dosyası sağlayarak ayrı ayrı işlevler veya kaynak dosyalar için CFI'yi seçerek devre dışı bırakabilirsiniz. Kara liste, derleyiciye belirtilen konumlarda CFI enstrümantasyonunu 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ümantasyonunu almayacak bireysel işlevleri seçmenize olanak tanır). Kara liste dosyasının formatı hakkında daha fazla ayrıntı için yukarı akışlı 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 CFI etkin değilken geçtiğinden emin olun.