Arm Bellek Etiketleme Uzantısı

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

MTE, her bellek ayırma/ayırma işlemini ek meta verilerle etiketler. MTE, bir bellek konumuna etiket atar. Bu etiket daha sonra söz konusu bellek konumuna referans veren işaretçilerle ilişkilendirilebilir. Çalışma zamanında CPU, her yükleme ve depolama işleminde işaretçi ile meta veri etiketlerinin eşleştiğini kontrol eder.

Android 12'de çekirdek ve kullanıcı alanı yığın bellek ayırıcısı, her ayırmaya meta veri ekleyebilir. Bu, kod tabanlarımızdaki bellek güvenliği hatalarının en yaygın kaynağı olan serbest bırakıldıktan sonra kullanma ve arabellek taşması hatalarının tespit edilmesine 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 tespitinin doğruluğu için optimize edilmiştir ve daha yüksek performans yükü kabul edilebilir olduğunda hassas bir hata tespit aracı olarak kullanılabilir. Etkinleştirildiğinde MTE SYNC, güvenlik riskini azaltma önlemi olarak işlev görür. Etiket uyuşmazlığı durumunda işlemci, yürütmeyi hemen durdurur ve SIGSEGV (kod SEGV_MTESERR) ile birlikte bellek erişimi ve hatalı adres hakkında tam bilgi vererek işlemi sonlandırır.

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

SYNC modunda çalışırken Android ayırıcı, tüm ayırma ve serbest bırakma işlemleri için yığın izlerini 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 izlerini 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 izlenmesini ve düzeltilmesini kolaylaştırır.

Eşzamansız mod (ASYNC)

Bu mod, hata raporlarının doğruluğundan ziyade performans için optimize edilmiştir ve bellek güvenliği hataları için düşük ek yükle algılama olarak kullanılabilir. Etiket uyuşmazlığı durumunda işlemci, en yakın çekirdek girişine (ör. bir sistem çağrısı veya zamanlayıcı kesmesi) kadar yürütmeye devam eder. Burada, hataya neden olan adresi veya bellek erişimini kaydetmeden SIGSEGV (kod SEGV_MTEAERR) ile işlemi sonlandırır.

Bu modu, test sırasında SYNC modu kullanılarak elde edilen ve 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 performansla bellek okumalarında eşzamanlı kontrol ve bellek yazmalarında eşzamansız kontrol sağlar. Bu mod çoğu durumda ASYNC moduna göre daha iyi sonuçlar verir. Bu nedenle, kullanılabilir 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, eşzamansızlık istendiğinde işletim sistemi her zaman asimetrik modu kullanacak şekilde yapılandırılabilir. Daha fazla bilgi için CPU'ya özel tercih edilen MTE düzeyini yapılandırma başlıklı makaleyi inceleyin.

Kullanıcı alanındaki MTE

Aşağıdaki bölümlerde, MTE'nin sistem süreçleri ve uygulamalar için nasıl etkinleştirilebileceği açıklanmaktadır. Aşağıdaki seçeneklerden biri belirli bir işlem için ayarlanmadığı sürece MTE varsayılan olarak devre dışıdır (MTE'nin hangi bileşenler için etkinleştirildiğini aşağıda görebilirsiniz).

Derleme sistemini kullanarak MTE'yi etkinleştirme

MTE, süreç genelinde bir özellik olarak ana yürütülebilir dosyanın derleme süresi ayarı tarafından kontrol edilir. Aşağıdaki seçenekler, bu ayarın tek tek yürütülebilir dosyalar veya kaynak ağacındaki alt dizinlerin tamamı için değiştirilmesine olanak tanır. Kitaplıklarda veya ne yürütülebilir ne de test olan herhangi bir hedefte ayarı yoksayılır.

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

MTE Modu Ayar
Eşzamansız MTE
  sanitize: {
  memtag_heap: true,
  }
Eşzamanlı 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ğacındaki bir alt dizinde MTE'yi etkinleştirme:

MTE modu Dahil etme listesi Hariç tutma listesi
async 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
Eşzamansız MTE MEMTAG_HEAP_ASYNC_INCLUDE_PATHS
Eşzamanlı MTE MEMTAG_HEAP_SYNC_INCLUDE_PATHS

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

MTE Modu Ayar
Eşzamansız MTE PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS MEMTAG_HEAP_EXCLUDE_PATHS
Eşzamanlı 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 özelliği 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ı ifade 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'ı kullanın.

Ortam değişkeni kullanarak MTE'yi etkinleştirme

Yerel işlemler (uygulama olmayan) için 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 öncelikli olur.

Uygulamalar için MTE'yi etkinleştirme

Belirtilmemişse MTE varsayılan olarak devre dışıdır ancak MTE'yi kullanmak isteyen uygulamalar android:memtagMode'yı <application> veya AndroidManifest.xml içindeki <process> etiketi altında ayarlayarak bunu yapabilir.

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

<application> etiketinde ayarlandığında, özelliği uygulamanın kullandığı tüm işlemleri etkiler ve etiketi ayarlanarak tek tek işlemler için geçersiz kılınabilir. <process>

Deneme için, manifest dosyasında herhangi bir değer belirtmeyen (veya default belirten) bir uygulamanın memtagMode özelliğinin varsayılan değerini ayarlamak üzere uyumluluk değişiklikleri kullanılabilir.

Bu ayarlar, genel ayar menüsündeki Sistem > Gelişmiş > Geliştirici seçenekleri > Uygulama Uyumluluğuyla İlgili Değişiklikler bölümünde yer alır. NATIVE_MEMTAG_ASYNC veya NATIVE_MEMTAG_SYNC ayarı, belirli bir uygulama için MTE'yi etkinleştirir. Alternatif olarak, bu ayar am komutu kullanılarak aşağıdaki şekilde de ayarlanabilir:

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

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

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

Geliştirme sırasında tüm yerel ikili dosyalarda 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şkenlerde olduğu gibi SANITIZE_TARGET, ortam değişkeni veya make ayarı olarak kullanılabilir (örneğin, product.mk dosyasında).

Bu işlem, tüm yerel işlemler için MTE'yi etkinleştirir ancak zygote64'dan çatallanan uygulamalar için etkinleştirmez. Bu uygulamalarda MTE, Uygulamalar için MTE'yi etkinleştirme bölümündeki talimatlar uygulanarak etkinleştirilebilir.

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

Bazı CPU'larda ASYMM veya SYNC modlarındaki MTE performansı ASYNC modundakiyle benzer olabilir. Bu nedenle, daha az katı bir kontrol modu istendiğinde bu CPU'larda daha katı kontrollerin etkinleştirilmesi, performansla ilgili dezavantajlar olmadan daha katı kontrollerin hata algılama avantajlarından yararlanmak için faydalı olur.

Varsayılan olarak, ASYNC modunda çalışacak şekilde yapılandırılan 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 önyükleme sırasında sysfs girişine /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred değeri yazılmalıdır. Bu işlem, bir başlatma komut dosyasıyla yapılabilir. Örneğin, 0-1 numaralı CPU'ları ASYNC modundaki işlemleri SYNC modunda çalıştıracak, 2-3 numaralı CPU'ları ise ASYMM modunda çalışacak şekilde yapılandırmak için satıcı başlatma komut dosyasının başlatma ifadesine 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ı, bellek hatasının konumunun tam yığın izleme (stack trace) içerir. Ancak bunlar, bir ayırma veya ayırmayı kaldırma yığını izleme (stack trace) içermez. Bu yığın izleri 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'dir.

malloc'ta bellek başlatmayı devre dışı bırakır ve doğruluk için gerekli olmadıkça bellek etiketlerini değiştirmekten kaçınır.

int mallopt(M_MEMTAG_TUNING, level)

Buradaki level şunlardan biridir:

  • M_MEMTAG_TUNING_BUFFER_OVERFLOW
  • M_MEMTAG_TUNING_UAF

Etiket dağıtım stratejisini seçer.

  • Varsayılan ayar M_MEMTAG_TUNING_BUFFER_OVERFLOW'dır.
  • M_MEMTAG_TUNING_BUFFER_OVERFLOW, bitişik ayırmalara farklı etiket değerleri atayarak doğrusal arabellek taşması ve yetersizliği hatalarının deterministik olarak algılanmasını sağlar. 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ın algılanma olasılığı biraz daha düşüktür. MTE, aynı etiket granülü (16 baytlık hizalı parça) içindeki taşmaları algılayamaz ve bu modda bile küçük taşmaları kaçırabilir. Bir granül içindeki bellek hiçbir zaman birden fazla tahsis için kullanılmadığından bu tür bir taşma, bellek bozulmasına neden olamaz.
  • M_MEMTAG_TUNING_UAF, hem mekansal (arabellek taşması) hem de zamansal (boşaltıldıktan sonra kullanma) hataların yaklaşık% 93 olasılıkla tespit edilmesi için bağımsız olarak rastgele oluşturulmuş etiketleri etkinleştirir.

Yukarıda açıklanan API'lere ek olarak, deneyimli kullanıcılar aşağıdakiler hakkında bilgi sahibi olmak isteyebilir:

  • PSTATE.TCO donanım kaydını ayarlamak, etiket kontrolünü geçici olarak devre dışı bırakabilir (örnek). Örneğin, bilinmeyen etiket içeriklerine sahip bir bellek aralığını kopyalarken veya sıcak döngüdeki performans darboğazını ele alırken.
  • M_HEAP_TAGGING_LEVEL_SYNC kullanılırken sistem kilitlenme işleyicisi, ayırma ve ayırmayı kaldı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şareti iletilerek etkinleştirilir. Kendi sinyal işleyicisini ayarlayan ve bilinmeyen kilitlenmeleri sisteme devreden tüm programların da aynı işlemi yapması önerilir.

Çekirdekte MTE

Çekirdek için MTE ile hızlandırılmış KASAN'ı etkinleştirmek üzere ç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.

Aşağıdaki komut satırı bağımsız değişkenlerini kullanarak bunu başlatma sırasında kontrol edebilirsiniz:

  • 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: kasan.mode=[sync|async])sync
  • kasan.stacktrace=[on|off]: Yığın izlerinin toplanıp toplanmayacağı (varsayılan: on)
    • yığın izleme (stack trace) toplama işlemi için de stack_depot_disable=off gerekir.
  • kasan.fault=[report|panic] - Yalnızca raporun yazdırılıp yazdırılmayacağı veya çekirdeğin de panik yapıp yapmayacağı (varsayılan: report). Bu seçenekten bağımsız olarak, ilk bildirilen hatadan sonra etiket kontrolü devre dışı bırakılır.

Başlatma, geliştirme ve test sırasında SYNC modunu kullanmanızı önemle tavsiye ederiz. Bu seçenek, ortam değişkenini kullanan veya derleme sistemiyle çalışan 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ı dengelenir ve hataları üretimde daha sonra tespit etmenin 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 ek yüke sahip bir araç ve daha fazla derinlemesine savunma sağlar. Bir hata tespit edildiğinde geliştirici, çalışma zamanı API'lerinden yararlanarak SYNC moduna geçebilir ve örneklenmiş bir kullanıcı grubundan doğru bir yığın izi alabilir.

Çip üzerinde sistem 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'ye tercih edilir. Küçük sıralı çekirdekler genellikle üç modda da benzer performans gösterir ve SYNC'yi tercih edecek şekilde yapılandırılabilir.

Geliştiriciler, /data/tombstones kontrol ederek, logcat kontrol ederek veya son kullanıcı hataları için satıcı DropboxManager ardışık düzenini izleyerek çökmelerin olup olmadığını kontrol etmelidir. Android yerel kodunda hata ayıklama hakkında daha fazla bilgi için buradaki bilgilere bakın.

MTE'nin etkinleştirildiği platform bileşenleri

Android 12'de, güvenlikle ilgili kritik öneme sahip bazı sistem bileşenleri, son kullanıcı kilitlenmelerini tespit etmek ve derinlemesine savunma için ek bir katman görevi görmek üzere MTE ASYNC kullanır. Bu bileşenler şunlardır:

  • Ağ oluşturma 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 kullanmayı 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 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 gecikmeye neden olmaz)

Tedarikçilerin, yukarıda belirtilen ölçütlere uyarak daha fazla bileşen için üretimde MTE'yi etkinleştirmesini öneririz. Geliştirme sırasında, kolayca düzeltilebilen hataları tespit etmek ve ASYNC'nin performans üzerindeki etkisini değerlendirmek için bu bileşenleri SYNC modunda test etmenizi öneririz.

Gelecekteki donanım tasarımlarının performans özelliklerine göre, MTE'nin etkinleştirildiği sistem bileşenlerinin listesini genişletmeyi planlıyoruz.