Arm bellek etiketleme uzantısı

Arm v9, etiketli belleğin donanım uygulaması olan Arm Bellek Etiketleme Uzantısı'nı (MTE) kullanıma sunar.

MTE, üst düzeyde her bellek ayırma/ayrılma işlemini ek meta veri ile etiketler. Bir bellek konumuna etiket atar. Bu etiket daha sonra söz konusu bellek konumuna atıfta bulunan işaretçilerle ilişkilendirilebilir. CPU, çalışma zamanında her yükleme ve depolama işleminde işaretçinin ve meta veri etiketlerinin eşleşip eşleşmediğini kontrol eder.

Android 12'de çekirdek ve kullanıcı alanı yığın bellek ayırıcısı her ayırmayı meta veri ile artırabilir. Bu, kod tabanlarımızda bellek güvenliğiyle ilgili hataların en yaygın kaynağı olan, serbest bırakıldıktan sonra kullanma ve arabellek taşması hatalarını tespit etmemize yardımcı olur.

MTE çalışma modları

MTE'nin üç çalışma modu vardır:

  • Eşzamanlı mod (SYNC)
  • Eşzamansız mod (ASYNC)
  • Asimetrik mod (ASYMM)

Eşzamanlı mod (SYNC)

Bu mod, performans yerine hata algılamanın doğruluğu için optimize edilmiştir ve daha yüksek performans yükü kabul edilebilir olduğunda hassas bir hata algılama aracı olarak kullanılabilir. MTE SYNC etkinleştirildiğinde güvenlik azaltıcı bir unsur olarak çalışır. Etiket uyuşmazlığı olduğunda işlemci yürütmeyi hemen durdurur ve işlemi SIGSEGV (SEGV_MTESERR kodu) ile sonlandırır. Ayrıca bellek erişimi ve hatalı adres hakkında tüm bilgileri de sağlar.

Bu modu, HWASan/KASAN'a alternatif olarak test sırasında veya hedef işlem savunmasız bir saldırı yüzeyi temsil ettiğinde üretimde kullanmanızı öneririz. Ayrıca, ASYNC modu bir hata olduğunu belirttiğinde, yürütmeyi SYNC moduna geçirmek için çalışma zamanı API'leri kullanılarak doğru bir hata raporu elde edilebilir.

Android ayırıcı, SYNC modunda çalışırken tüm ayırma ve boşaltma işlemlerinin yığın izlemelerini kaydeder ve bunları, boşaltıldıktan sonra kullanım veya arabellek taşması gibi bir bellek hatasının açıklamasını ve ilgili bellek etkinliklerinin yığın izlemelerini içeren daha iyi hata raporları sağlamak için kullanır. Bu tür raporlar daha fazla bağlamsal bilgi sağlar ve hataların izlenip düzeltilmesini kolaylaştırır.

Eşzamansız mod (ASYNC)

Bu mod, hata raporlarının doğruluğu yerine performans için optimize edilmiştir ve hafıza güvenliği hatalarında düşük maliyetli algılama olarak kullanılabilir.
Etiket uyuşmazlığı olduğunda işlemci, en yakın çekirdek girişine (ör. sistem çağrısı veya zamanlayıcı kesintisi) kadar yürütmeye devam eder. Burada, hatalı adresi veya bellek erişimini kaydetmeden işlemi SIGSEGV (kod SEGV_MTEAERR) ile sonlandırır.
Bu modu, test sırasında SYNC modu kullanılarak bellek güvenliği hatalarının yoğunluğunun düşük olduğu bilinen, iyi test edilmiş kod tabanlarında üretimde kullanmanızı öneririz.

Asimetrik mod (ASYMM)

Arm v8.7-A'daki ek bir özellik olan Asimetrik MTE modu, ASYNC moduna benzer bir performansla hafıza okumalarında eşzamanlı kontrol ve hafıza yazma işlemlerinde eşzamansız kontrol sağlar. Çoğu durumda bu mod, ASYNC moduna kıyasla bir iyileştirmedir ve mümkün olduğunda ASYNC yerine bu modu kullanmanızı öneririz.

Bu nedenle, aşağıda açıklanan API'lerin hiçbirinde asimetrik moddan bahsedilmez. Bunun yerine, işletim sistemi Asenkron istek alındığında her zaman Asimmetrik modu kullanacak şekilde yapılandırılabilir. Daha fazla bilgi için lütfen "CPU'ya özel tercih edilen MTE düzeyini yapılandırma" bölümüne bakın.

Kullanıcı alanında MTE

Aşağıdaki bölümlerde, MTE'nin sistem işlemleri ve uygulamalar için nasıl etkinleştirilebileceği açıklanmaktadır. Belirli bir işlem için aşağıdaki seçeneklerden biri ayarlanmadıkça MTE varsayılan olarak devre dışıdır (Aşağıda MTE'nin hangi bileşenler için etkinleştirildiğine bakın).

Derleme sistemini kullanarak MTE'yi etkinleştirme

MTE, süreç genelinde bir özellik olduğundan ana yürütülebilir dosyanın derleme zamanı ayarı tarafından kontrol edilir. Aşağıdaki seçenekler, bu ayarı tek tek yürütülebilir dosyalar veya kaynak ağacındaki alt dizinlerin tamamı için değiştirmenize olanak tanır. Bu ayar, kitaplıklarda veya yürütülebilir ya da test olmayan hedeflerde yoksayılır.

1. Belirli bir proje için Android.bp (örnek) uygulamasında MTE'yi etkinleştirme:

MTE Modu Ayar
Asenkron MTE
  sanitize: {
  memtag_heap: true,
  }
Senkronize MTE
  sanitize: {
  memtag_heap: true,
  diag: {
  memtag_heap: true,
  },
  }

veya Android.mk:

MTE Modu Ayar
Asynchronous MTE LOCAL_SANITIZE := memtag_heap
Synchronous MTE LOCAL_SANITIZE := memtag_heap
LOCAL_SANITIZE_DIAG := memtag_heap

2. Bir ürün değişkeni kullanarak kaynak ağaçtaki bir alt dizinde MTE'yi etkinleştirme:

MTE modu Dahil etme listesi Hariç tutma listesi
eş zamansız PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS MEMTAG_HEAP_ASYNC_INCLUDE_PATHS PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
senkronizasyon PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS MEMTAG_HEAP_SYNC_INCLUDE_PATHS

veya

MTE Modu Ayar
Asenkron MTE MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
Senkronize MTE MEMTAG_HEAP_SYNC_INCLUDE_PATHS

veya bir yürütülebilir dosyanın hariç tutma yolunu belirterek:

MTE Modu Ayar
Asenkron MTE PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
Senkronize MTE

Örnek, (PRODUCT_CFI_INCLUDE_PATHS ile benzer kullanım)

  PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS=vendor/$(vendor)
  PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS=vendor/$(vendor)/projectA \
                                    vendor/$(vendor)/projectB

Sistem özelliklerini kullanarak MTE'yi etkinleştirme

Yukarıdaki derleme ayarları, aşağıdaki sistem mülkü ayarlanarak çalışma zamanında geçersiz kılınabilir:

arm64.memtag.process.<basename> = (off|sync|async)

Burada basename, yürütülebilir dosyanın temel adını temsil eder.

Örneğin, /system/bin/ping veya /data/local/tmp/ping'ü eşzamansız MTE kullanacak şekilde ayarlamak için adb shell setprop arm64.memtag.process.ping async değerini kullanın.

MTE'yi bir ortam değişkeni kullanarak etkinleştirme

Derleme ayarını geçersiz kılmanın bir başka yolu da ortam değişkenini tanımlamaktır: MEMTAG_OPTIONS=(off|sync|async) Hem ortam değişkeni hem de sistem özelliği tanımlanmışsa değişken önceliklidir.

Uygulamalar için MTE'yi etkinleştirme

Belirtilmemişse MTE varsayılan olarak devre dışıdır ancak MTE kullanmak isteyen uygulamalar, AndroidManifest.xml içinde <application> veya <process> etiketinin altına android:memtagMode ayarlayarak bunu yapabilir.

android:memtagMode=(off|default|sync|async)

<application> etiketinde ayarlandığında bu özellik, uygulama tarafından kullanılan tüm işlemleri etkiler ve <process> etiketi ayarlanarak ayrı ayrı işlemler için geçersiz kılınabilir.

Deneme amacıyla, manifest dosyasında herhangi bir değer belirtmeyen (veya default değerini belirten) bir uygulama için memtagMode özelliğinin varsayılan değerini ayarlamak üzere uyumluluk değişiklikleri kullanılabilir.
Bu değişikliklere genel ayar menüsündeki System > Advanced > Developer options > App Compatibility Changes bölümünden ulaşabilirsiniz. NATIVE_MEMTAG_ASYNC veya NATIVE_MEMTAG_SYNC ayarını yaptığınızda belirli bir uygulama için MTE etkinleştirilir.
Alternatif olarak, bu ayar am komutu kullanılarak aşağıdaki gibi ayarlanabilir:

$ adb shell am compat enable NATIVE_MEMTAG_[A]SYNC my.app.name

MTE sistem görüntüsü oluşturma

Geliştirme ve kullanıma sunma sırasında tüm yerel ikililerde MTE'yi etkinleştirmenizi önemle tavsiye ederiz. Bu, bellek güvenliği hatalarının erken tespit edilmesine yardımcı olur ve test yapılarında etkinleştirilirse gerçekçi kullanıcı kapsamı sağlar.

Geliştirme sırasında tüm yerel ikililerde MTE'yi senkron modda etkinleştirmenizi önemle tavsiye ederiz.

SANITIZE_TARGET=memtag_heap SANITIZE_TARGET_DIAG=memtag_heap m

Derleme sistemindeki tüm değişkenler gibi SANITIZE_TARGET de ortam değişkeni veya make ayarı olarak kullanılabilir (ör. product.mk dosyasında).
Bu işlemin, MTE'nin yukarıdaki talimatları izleyerek etkinleştirilebileceği uygulamalar (zygote64'dan ayrılmış) için değil, tüm doğal işlemler için etkinleştirileceğini lütfen unutmayın.

CPU'ya özgü tercih edilen MTE düzeyini yapılandırma

Bazı CPU'larda, ASYMM veya hatta SYNC modlarında MTE'nin performansı ASYNC'e benzer olabilir. Bu nedenle, daha az katı bir kontrol modu istendiğinde bu CPU'larda daha katı kontrolleri etkinleştirmek faydalı olur. Böylece, performans açısından olumsuz sonuçlara yol açmadan daha katı kontrollerin hata algılama avantajlarından yararlanabilirsiniz.
Varsayılan olarak, ASYNC modunda çalışacak şekilde yapılandırılmış işlemler tüm CPU'larda ASYNC modunda çalışır. Çekirdeği, bu işlemleri belirli CPU'larda SYNC modunda çalıştıracak şekilde yapılandırmak için değer senkronizasyonu, önyükleme sırasında sysfs girişine /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred yazılmalıdır. Bu işlem bir başlatma komut dosyasıyla yapılabilir. Örneğin, 0-1 arasındaki CPU'ları ASYNC modu işlemlerini SYNC modunda çalıştıracak, 2-3 arasındaki CPU'ları ise ASYMM modunda çalıştıracak şekilde yapılandırmak için bir tedarikçi firmanın init komut dosyasının init yan tümcesine aşağıdakiler eklenebilir:

  write /sys/devices/system/cpu/cpu0/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu1/mte_tcf_preferred sync
  write /sys/devices/system/cpu/cpu2/mte_tcf_preferred asymm
  write /sys/devices/system/cpu/cpu3/mte_tcf_preferred asymm

SYNC modunda çalışan ASYNC modu işlemlerinden gelen mezar taşları, hafıza hatasının konumunun tam yığın izlemesini içerir. Ancak bu raporlar, bir ayırma veya ayırma sonlandırma yığın izlemesi içermez. Bu yığın izlemeleri yalnızca işlem SYNC modunda çalışacak şekilde yapılandırılmışsa kullanılabilir.

int mallopt(M_THREAD_DISABLE_MEM_INIT, level)

Burada level 0 veya 1 değerini alır.
malloc'ta bellek başlatmayı devre dışı bırakır ve doğruluk için gerekli olmadığı sürece bellek etiketlerinin değiştirilmesini önler.

int mallopt(M_MEMTAG_TUNING, level)

Buradaki level şu anlamlara gelir:

  • M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_UAF

Etiket atama stratejisini seçer.

  • Varsayılan ayar M_MEMTAG_TUNING_BUFFER_OVERFLOW'tir.
  • M_MEMTAG_TUNING_BUFFER_OVERFLOW: Bitişik atamalara farklı etiket değerleri atayarak doğrusal arabelleğe taşma ve aksama hatalarının belirlenebilir şekilde algılanmasına olanak tanır. Bu modda, her bellek konumu için olası etiket değerlerinin yalnızca yarısı kullanılabildiğinden, serbest bırakıldıktan sonra kullanma hatalarını algılama şansı biraz daha düşüktür. MTE'nin aynı etiket granülü (16 baytlık hizalanmış parça) içinde taşmayı algılayamayacağını ve bu modda bile küçük taşmaları kaçırabileceğini lütfen unutmayın. Bir granüldeki bellek hiçbir zaman birden fazla tahsis için kullanılmadığından, bu tür taşmalar bellek bozulmasına neden olamaz.
  • M_MEMTAG_TUNING_UAF: Hem mekansal (arabellek taşması) hem de zamansal (serbest bırakıldıktan sonra kullanma) hataları algılama olasılığının eşit olması için bağımsız olarak rastgele etiketler etkinleştirir.

Deneyimli kullanıcılar, yukarıda açıklanan API'lere ek olarak aşağıdakileri de göz önünde bulundurabilir:

  • PSTATE.TCO donanım kaydını ayarlamak, etiket kontrolünü geçici olarak devre dışı bırakabilir (örnek). Örneğin, bilinmeyen etiket içeriğine sahip bir bellek aralığını kopyalarken veya yoğun döngüdeki bir performans darboğazını ele alırken.
  • M_HEAP_TAGGING_LEVEL_SYNC kullanılırken sistem kilitlenme işleyicisi, ayırma ve ayırma yığın izlemeleri gibi ek bilgiler sağlar. Bu işlev için etiket bitlerine erişim gerekir ve sinyal işleyici ayarlanırken SA_EXPOSE_TAGBITS işaretçisi ile etkinleştirilir. Kendi sinyal işleyicisini ayarlayan ve bilinmeyen kilitlenmeleri sistem işleyicisine delege eden programların da aynısını yapması önerilir.

Çekirdekte MTE

Çekirdek için MTE hızlandırılmış KASAN'ı etkinleştirmek isterseniz çekirdeği CONFIG_KASAN=y, CONFIG_KASAN_HW_TAGS=y ile yapılandırın. Bu yapılandırmalar, Android 12-5.10 sürümünden itibaren GKI çekirdeklerinde varsayılan olarak etkindir.
Bu, aşağıdaki komut satırı bağımsız değişkenleri kullanılarak önyükleme sırasında kontrol edilebilir:

  • kasan=[on|off]: KASAN'ı etkinleştirin veya devre dışı bırakın (varsayılan: on)
  • kasan.mode=[sync|async]: eşzamanlı ve eşzamansız mod arasında seçim yapın (varsayılan: sync)
  • kasan.stacktrace=[on|off]: yığın izlemelerin toplanıp toplanmayacağı (varsayılan: on)
    • yığın izleme toplama işlemi için stack_depot_disable=off de gereklidir.
  • kasan.fault=[report|panic]: Yalnızca raporun yazdırılıp yazdırılmayacağı veya çekirdeğin de paniğe kapatılıp kapatılmayacağı (varsayılan: report). Bu seçenekten bağımsız olarak, bildirilen ilk hatadan sonra etiket kontrolü devre dışı bırakılır.

Kurulum, geliştirme ve test sırasında SYNC modunu kullanmanızı önemle tavsiye ederiz. Bu seçenek, ortam değişkeni veya derleme sistemi kullanılarak tüm işlemler için genel olarak etkinleştirilmelidir. Bu modda hatalar geliştirme sürecinin erken aşamalarında tespit edilir, kod tabanı daha hızlı kararlı hale gelir ve hataların üretimde daha sonra tespit edilmesinin maliyeti önlenir.

Üretimde ASYNC modunu kullanmanızı önemle tavsiye ederiz. Bu, bir süreçte bellek güvenliği hatalarının varlığını tespit etmek için düşük maliyetli bir araç sağlar ve daha ayrıntılı bir savunma sağlar. Bir hata algılandığında geliştirici, SYNC moduna geçmek ve örneklenmiş bir kullanıcı grubundan doğru bir yığın izleme bilgisi almak için çalışma zamanı API'lerinden yararlanabilir.

SoC için CPU'ya özel tercih edilen MTE düzeyini yapılandırmanızı önemle tavsiye ederiz. Asymm modu genellikle ASYNC ile aynı performans özelliklerine sahiptir ve neredeyse her zaman ASYNC'e tercih edilir. Küçük sıralı çekirdekler genellikle üç modun üçünde de benzer performans gösterir ve SYNC'i tercih edecek şekilde yapılandırılabilir.

Geliştiriciler, /data/tombstones'ü kontrol ederek veya logcat'i izleyerek ya da son kullanıcı hatalarını tespit etmek için tedarikçi DropboxManager ardışık düzenini izleyerek kilitlenme olup olmadığını kontrol etmelidir. Android doğal kodunda hata ayıklama hakkında daha fazla bilgi için buraya göz atın.

MTE etkin platform bileşenleri

Android 12'de, son kullanıcı kilitlenmelerini tespit etmek ve derinlemesine savunmanın ek bir katmanı olarak hareket etmek için güvenlik açısından kritik olan çeşitli sistem bileşenleri MTE ASYNC'i kullanır. Bu bileşenler şunlardır:

  • Ağ daemon'ları ve yardımcı programları (netd hariç)
  • Bluetooth, SecureElement, NFC HAL'leri ve sistem uygulamaları
  • statsd arka plan programı
  • system_server
  • zygote64 (uygulamaların MTE'yi etkinleştirmesine izin vermek için)

Bu hedefler aşağıdaki ölçütlere göre seçilmiştir:

  • Ayrıcalıklı bir işlem (unprivileged_app SELinux alanının erişemediği bir şeye erişimi olan bir işlem olarak tanımlanır)
  • Güvenilir olmayan girişleri işler (İki kural)
  • Kabul edilebilir performans yavaşlaması (yavaşlama, kullanıcı tarafından görülebilen gecikme oluşturmaz)

Tedarikçi firmaları, yukarıda belirtilen ölçütlere uygun olarak daha fazla bileşen için üretimde MTE'yi etkinleştirmeye teşvik ediyoruz. Geliştirme sırasında, kolayca düzeltilen hataları tespit etmek ve ASYNC modunun performans üzerindeki etkisini değerlendirmek için bu bileşenleri SYNC modunu kullanarak test etmenizi öneririz.
Android, gelecekte MTE'nin etkinleştirildiği sistem bileşenlerinin listesini, gelecekteki donanım tasarımlarının performans özelliklerine göre genişletmeyi planlıyor.