AArch64 İkili Dosyaları için Yalnızca Yürütme Belleği (XOM)

AArch64 sistem ikili dosyaları için yürütülebilir kod bölümleri, tam zamanında kodun yeniden kullanılması saldırılarına karşı bir önlem olarak varsayılan olarak yalnızca yürütme (okunamaz) olarak işaretlenmiştir. Verileri ve kodu bir araya getiren kod ve bu bölümleri (öncelikle bellek bölümlerini okunabilir olarak yeniden eşlemeden) bilinçli olarak denetleyen kod artık çalışmaz. Hedef SDK'sı 10 (API düzeyi 29 veya üzeri) olan uygulamalar, uygulamanın, önce bölümü okunabilir olarak işaretlemeden, bellekteki salt yürütme belleği (XOM) etkin sistem kitaplıklarının kod bölümlerini okumaya çalışması durumunda etkilenir.

Bu azaltımdan tam olarak yararlanabilmek için hem donanım hem de çekirdek desteği gereklidir. Bu destek olmadan, hafifletme yalnızca kısmen uygulanabilir. Android 4.9 ortak çekirdeği, ARMv8.2 cihazlarda bunun için tam destek sağlamak üzere uygun yamaları içerir.

Uygulama

Derleyici tarafından oluşturulan AArch64 ikili dosyaları, kod ve verilerin birbirine karıştırılmadığını varsayar. Bu özelliğin etkinleştirilmesi cihazın performansını olumsuz etkilemez.

Yürütülebilir bölümleri üzerinde kasıtlı bellek iç incelemesi yapması gereken kod için, okunabilir olmalarını sağlamak üzere inceleme gerektiren kod bölümleri üzerinde mprotect çağrılması, ardından inceleme tamamlandığında okunabilirliğin kaldırılması önerilir.
Bu uygulama, yalnızca yürütme olarak işaretlenen bellek bölümlerinin okunmasına ve bölümleme hatasına ( SEGFAULT ) neden olur. Bu, bir hatanın, güvenlik açığının, verilerin kodla karıştırılmasının (gerçek havuzlama) veya kasıtlı bellek iç gözleminin bir sonucu olarak ortaya çıkabilir.

Cihaz desteği ve etkisi

Gerekli yamaları olmayan, daha eski donanıma veya daha önceki çekirdeklere (4.9'dan düşük) sahip cihazlar bu özelliği tam olarak desteklemeyebilir veya bu özellikten yararlanamayabilir. Çekirdek desteği olmayan cihazlar, yalnızca yürütme belleğine kullanıcı erişimini zorunlu kılmayabilir, ancak bir sayfanın okunabilir olup olmadığını açıkça kontrol eden çekirdek kodu, process_vm_readv() gibi yine de bu özelliği zorlayabilir.

Çekirdeğin yalnızca yürütme olarak işaretlenmiş kullanıcı alanı sayfalarına saygı göstermesini sağlamak için çekirdekte CONFIG_ARM64_UAO çekirdek bayrağı ayarlanmalıdır. Daha eski ARMv8 aygıtları veya Kullanıcı Erişimini Geçersiz Kılma (UAO) devre dışı bırakılmış ARMv8.2 aygıtları bundan tam olarak yararlanamayabilir ve sistem çağrılarını kullanarak yalnızca yürütme sayfalarını okuyabilmeye devam edebilir.

Mevcut kodu yeniden düzenleme

AArch32'den taşınan kod, karışık veri ve kod içerebilir ve bu da sorunların ortaya çıkmasına neden olabilir. Çoğu durumda bu sorunları düzeltmek, sabitleri derleme dosyasındaki .data bölümüne taşımak kadar basittir.

Yerel olarak havuzda toplanan sabitleri ayırmak için el yazısı derlemenin yeniden düzenlenmesi gerekebilir.

Örnekler:

Clang derleyicisi tarafından oluşturulan ikili dosyalar, verilerin koda karıştırılmasıyla ilgili herhangi bir sorun yaşamamalıdır. GNU derleyici koleksiyonu (GCC) tarafından oluşturulan kod dahil edilmişse (statik bir kitaplıktan), sabitlerin kod bölümlerinde bir araya toplanmadığından emin olmak için çıktı ikili dosyasını inceleyin.

Yürütülebilir kod bölümlerinde kodun incelenmesi gerekiyorsa, önce kodu okunabilir olarak işaretlemek için mprotect çağırın. Daha sonra işlem tamamlandıktan sonra okunamaz olarak işaretlemek için mprotect tekrar arayın.

Etkinleştirme

Yalnızca yürütme, yapı sistemindeki tüm 64 bit ikili dosyalar için varsayılan olarak etkindir.

Devre dışı bırakılıyor

Yalnızca yürütmeyi modül düzeyinde, alt dizin ağacının tamamında veya yapının tamamı için genel olarak devre dışı bırakabilirsiniz.

XOM, yeniden düzenlenemeyen veya çalıştırılabilir kodlarını okuması gereken bireysel modüller için LOCAL_XOM ve xom değişkenlerini false olarak ayarlayarak devre dışı bırakılabilir.

// Android.mk
LOCAL_XOM := false

// Android.bp
cc_binary { // or other module types
   ...
   xom: false,
}

Statik bir kitaplıkta salt yürütme belleği devre dışı bırakılırsa, yapı sistemi bunu o statik kitaplığın tüm bağımlı modüllerine uygular. Bunu xom: true, kullanarak geçersiz kılabilirsiniz.

Belirli bir alt dizindeki (örneğin, foo/bar/) salt yürütme belleğini devre dışı bırakmak için değeri XOM_EXCLUDE_PATHS iletin.

make -j XOM_EXCLUDE_PATHS=foo/bar

Alternatif olarak ürün yapılandırmanızda PRODUCT_XOM_EXCLUDE_PATHS değişkenini ayarlayabilirsiniz.

make komutunuza ENABLE_XOM=false komutunu ileterek salt yürütme ikili dosyalarını genel olarak devre dışı bırakabilirsiniz.

make -j ENABLE_XOM=false

Doğrulama

Yalnızca yürütme belleği için CTS veya doğrulama testleri mevcut değildir. readelf kullanarak ve segment bayraklarını kontrol ederek ikili dosyaları manuel olarak doğrulayabilirsiniz.