AArch64 ikili dosyaları için salt yürütme belleği (XOM)

AArch64 sistem ikili dosyaları için yürütülebilir kod bölümleri, tam zamanında kod yeniden kullanma saldırılarına karşı bir sertleştirme azaltıcısı olarak varsayılan olarak yalnızca çalıştırılabilir (okunamaz) olarak işaretlenir. Verileri ve kodu birlikte karıştıran kodlar ve bu bölümleri kasıtlı olarak inceleyen kodlar (öncelikle bellek segmentlerini okunabilir olarak yeniden eşlemeden) artık çalışmaz. Hedef SDK'sı 10 (API düzeyi 29 veya daha yüksek) olan uygulamalar, önce bölümü okunabilir olarak işaretlemeden bellekte salt yürütme belleği (XOM) etkin sistem kitaplıklarının kod bölümlerini okumaya çalışırsa bu durumdan etkilenir.

Bu azaltma yönteminden tam olarak yararlanmak için hem donanım hem de çekirdek desteği gerekir. Bu destek olmadan azaltma yalnızca kısmen uygulanabilir. Android 4.9 ortak çekirdeği, ARMv8.2 cihazlarda bu özellik için tam destek sunacak uygun yamaları içerir.

Uygulama

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

Yürütülebilir segmentlerinde kasıtlı bellek incelemesi yapması gereken kodlarda, inceleme gerektiren kod segmentlerinin okunabilir olması için mprotect çağrılması ve inceleme tamamlandığında okunabilirliğin kaldırılması önerilir.
Bu uygulama, salt yürütme olarak işaretlenen bellek segmentlerinin okunmasının segmentasyon hatası (SEGFAULT) ile sonuçlanmasına neden olur. Bu durum, bir hata, güvenlik açığı, kodla karıştırılan veriler (doğrudan havuzlama) veya kasıtlı bellek iç gözlemi nedeniyle ortaya çıkabilir.

Cihaz desteği ve etkisi

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

Çekirdek, yalnızca çalıştırılabilir olarak işaretlenmiş kullanıcı alanı sayfalarına uyması için çekirdek işaretçisi CONFIG_ARM64_UAO'te ayarlanmalıdır. Daha eski ARMv8 cihazlar veya kullanıcı erişim geçersiz kılma (UAO) özelliği devre dışı bırakılmış ARMv8.2 cihazlar bu durumdan tam olarak yararlanamayabilir ve sistem çağrılarını kullanarak salt yürütme sayfalarını okumaya devam edebilir.

Mevcut kodu yeniden düzenleme

AArch32'den aktarılan kod, karışık veri ve kod içerebilir ve sorunlara neden olabilir. Çoğu durumda, bu sorunları düzeltmek için sabitleri derleme dosyasında bir .data bölümüne taşımanız yeterlidir.

El yazısıyla yazılmış derlemenin, yerel olarak havuzlanan sabitleri ayırmak için yeniden yapılandırılması gerekebilir.

Örnekler:

Clang derleyicisi tarafından oluşturulan ikili dosyalarda, veriler kodda karıştırıldığında herhangi bir sorun yaşanmaz. GNU derleyici koleksiyonu (GCC) tarafından oluşturulan kod dahil edilmişse (statik bir kitaplıktan) çıkış ikilisini inceleyerek sabitlerin kod bölümlerinde toplanmadığından emin olun.

Kod iç gözlemi, yürütülebilir kod bölümlerinde gerekliyse kodu okunabilir olarak işaretlemek için önce mprotect işlevini çağırın. Ardından, işlem tamamlandıktan sonra mprotect'ü tekrar arayarak okunamaz olarak işaretleyin.

XOM'u etkinleştirme

Yalnızca çalıştırma, derleme sistemindeki tüm 64 bit ikili programlar için varsayılan olarak etkindir.

XOM'u devre dışı bırakma

Yalnızca çalıştırma özelliğini modül düzeyinde, bir alt dizin ağacının tamamı için veya bir derlemenin tamamı için küresel olarak devre dışı bırakabilirsiniz.

XOM, LOCAL_XOM ve xom değişkenleri false olarak ayarlanarak yeniden yapılandıramayan veya yürütülebilir kodlarının okunması gereken modüller için 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 derleme sistemi bunu söz konusu statik kitaplığın tüm bağımlı modüllerine uygular. xom: true, kullanarak bu ayarı geçersiz kılabilirsiniz.

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

make -j XOM_EXCLUDE_PATHS=foo/bar

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

make komutunuza ENABLE_XOM=false ileterek yalnızca çalıştırılabilir ikili dosyaları dünya genelinde devre dışı bırakabilirsiniz.

make -j ENABLE_XOM=false

Doğrulama

Yalnızca yürütme amaçlı bellek için CTS veya doğrulama testi yoktur. readelf kullanarak ve segment işaretlerini kontrol ederek ikili dosyaları manuel olarak doğrulayabilirsiniz.