- CVE-2023-6241, Arm Mali GPU bellek yönetim birimindeki bir mantık hatasıdır; kötü amaçlı bir Android uygulamasının, kernel MTE açık olan Pixel 8’de bile keyfi kernel kodu çalıştırmaya ve root yetkisi elde etmeye ulaşmasına olanak tanır
- Etkilenenler, Command Stream Frontend(CSF) kullanan yeni Arm Mali GPU cihazlarıdır; Google Pixel 7 ve Pixel 8 buna dahildir
- Zafiyet, JIT bellek genişletme sırasında kilidin kısa süreliğine açıldığı aralıktan yararlanarak GPU eşlemesi ile backing page dizisi arasında tutarsızlık oluşturma şeklinde çalışır
- Exploit, serbest bırakılmış backing page üzerinde kalan GPU eşlemesini kullanır; bu sayfanın GPU bağlamının PGD’si olarak yeniden kullanılmasını sağladıktan sonra kernel belleğini ve kernel kodunu eşler
- MTE, pointer ve bellek tag’i uyuşmazlıklarını yakalar; ancak bu saldırı akışı, GPU’nun fiziksel adreslere doğrudan erişmesiyle MTE koruma kapsamı dışında ilerler
Zafiyet kapsamı ve yama durumu
- CVE-2023-6241, Arm Mali GPU zafiyetidir; kötü amaçlı bir Android uygulamasının cihazda keyfi kernel kodu çalıştırmasına ve root yetkisi almasına olanak tanır
- 15 Kasım 2023’te Arm’a bildirildi ve 14 Aralık 2023’te yayımlanan Arm Mali driver r47p0 sürümünde düzeltildi
- Android düzeltmeleri Mart 2024 güvenlik güncellemesine dahil edildi
- Etkilenenler, CSF(Command Stream Frontend) özelliğini kullanan yeni Arm Mali GPU cihazlarıdır; Google Pixel 7 ve Pixel 8 örnek olarak gösteriliyor
- Pixel 8’de kernel MTE etkinleştirilmişken de exploit’in çalıştığı doğrulandı
Arm64 MTE’nin savunma modeli
- MTE(Memory Tagging Extension), modern Arm işlemcilerde bulunan, bellek bozulmasını tespit etmek için pointer’lar ile bellek bloklarının tag’lerini karşılaştıran bir donanım özelliğidir
- Arm64 pointer’ları 64 bit olsa da gerçek uygulama adres alanı genellikle 52 bit veya daha az olduğundan üst bitlerin bir kısmı tag saklamak için kullanılabilir
- Doğrusal overflow durumunda bitişik bellek bloklarının tag’i pointer tag’inden farklılaşabilir; use-after-free durumunda ise serbest bırakma ve yeniden ayırma sürecindeki tag değişimi nedeniyle uyuşmazlık oluşabilir
- kCFI gibi sonraki aşama azaltma önlemlerinin aksine MTE, bellek bozulmasını ilk oluştuğu anda yakalamayı hedefleyen erken aşama bir azaltma önlemidir
- Tag bitlerinin sayısı sınırlı olduğundan çakışmalar kaçınılmazdır; yalnızca 4 bit tag kullanılsa bile rastgele başarı olasılığı 1/16’ya düşer
- Spectre gibi yan kanal saldırılarıyla pointer ve bellek bloğu değerleri sızdırılırsa doğru tag tutturularak MTE atlatılabilir; ancak bu tür sızıntılar çoğunlukla yerel saldırganlar için mümkündür
- Şu anda yalnızca Google Pixel 8, geliştirici seçeneklerinden MTE’nin etkinleştirilmesine izin verir; MTE varsayılan olarak devre dışıdır
- Kernel’de MTE’yi etkinleştirmek için ek prosedür gerekir
Mali JIT belleğinde oluşan yarış durumu
- Mali GPU driver’ını kullanan kullanıcı uygulaması, driver dosyasını açar ve
ioctlçağrılarıylakbase_contextkernel nesnesini oluşturup başlatır kbase_context, GPU cihazı ile kullanıcı alanı uygulaması arasında paylaşılan çeşitli bellek türlerini yönetir- Mali GPU’nun bellek bölgesi
kbase_va_regionile temsil edilir;nr_pagessanal boyutu,gpu_alloc->nentsise gerçek backing page sayısını gösterir - JIT belleği, ömrü kernel driver tarafından yönetilen native memory’dir; uygulama JIT belleğini GPU komutlarıyla ayırır veya serbest bırakır
- CSF GPU’larda yazılım komutları ve donanım komutları farklı kuyruklara konur
KBASE_IOCTL_KCPU_QUEUE_CREATEilekbase_kcpu_command_queueoluşturulabilirKBASE_IOCTL_KCPU_QUEUE_ENQUEUEile komutlar kuyruğa eklenirBASE_KCPU_COMMAND_TYPE_JIT_ALLOCveBASE_KCPU_COMMAND_TYPE_JIT_FREE, JIT ayırma ve serbest bırakma için kullanılır
kbase_jit_allocate, serbest bırakılmış JIT bellek havuzunda yeniden kullanılabilir bir bölge arar; fiziksel boyut yetersizsekbase_jit_growile backing page sayısını artırırkbase_jit_grow,kbase_mem_pool_growçağrısı sırasındakctx->reg_lockvekctx->mem_partials_lockkilitlerini geçici olarak bırakabilirkctx->reg_lock, bellek bölgelerine eşzamanlı erişimi koruduğundan kilidin açıldığı aralık bir yarış penceresi hâline gelir
CVE-2023-6241 tetikleme akışı
- GPU, fiziksel sayfalarla backing edilmemiş bir bellek bölgesi adresine erişirse GPU bellek erişim hatası oluşur
kbase_mmu_page_fault_worker, bölgenin genişletilebilir olup olmadığını kontrol ettikten sonra gerekli backing page’leri hemen ayırıp eşleyebilir- JIT bölgesi oluşturulurken
KBASE_REG_PF_GROWveKBASE_REG_GPU_WRiçeren GROWABLE_FLAGS_REQUIRED koşulunu karşılar - JIT bölgesi serbest bırakılırken eklenen
KBASE_REG_DONT_NEEDflag’i,kbase_jit_growbaşındakikbase_mem_evictable_unmakeiçinde kaldırılır - Sonuç olarak
kbase_mem_pool_growçalışırken oluşan yarış penceresinde aynı JIT bölgesinde GPU page fault oluşturulursa fault handler bu bölgeyi genişletebilir - Fault handler
reg->gpu_alloc->nentsdeğerini değiştirirse,kbase_jit_grow’un daha önce sakladığıold_sizevedeltadeğerleri gerçek durumla uyumsuz hâle gelir - Ardından
kbase_alloc_phy_pages_helper_lockedvekbase_mem_grow_gpu_mapping, stale değerlerle backing page ayırma ve GPU eşleme işlemleri yaptığında GPU eşlemesi ilepagesdizisi arasında tutarsızlık oluşur - Bu yarış,
kbase_mem_pool_growbüyük bellek ayırma işlemi içerdiği için kolayca kazanılabilir
GHSL-2023-005 yamasından sonra değişen saldırı yöntemi
- Önceki zafiyet GHSL-2023-005 kapsamında başka bir thread,
KBASE_IOCTL_MEM_COMMITile JIT bölgesini küçülterekold_sizevedeltadeğerlerini geçersiz kılabiliyordu - GHSL-2023-005 yamasından sonra
KBASE_IOCTL_MEM_COMMIT ioctlile JIT bellek boyutu değiştirilemez hâle geldi - CVE-2023-6241’de yarış penceresinde bölge küçültülemiyor, yalnızca büyütülebiliyor
- Sadece büyütme durumunda son bazı backing page’ler GPU’ya eşlenmemiş olur; ancak baştan itibaren sürekli eşlenmiş yapı korunduğu için bu hemen sorun yaratmaz
- Exploit, ek GPU fault’larıyla unmapped gap’in arkasında yeni eşleme oluşturur; ardından JIT serbest bırakma yoluyla shrink başlangıç noktasını bu gap’in içine denk getirerek istismar edilebilir bir durum oluşturur
GPU eşleme kaldırmadaki zayıf varsayım
kbase_mmu_teardown_pgd_pages, GPU sayfa tablolarını dolaşarak entry’leri invalid olarak işaretler ve GPU adres eşlemesini kaldırır- Bu fonksiyon, daha yüksek seviyeli PTE invalid ise o entry’nin kapsadığı büyük adres aralığının tamamının zaten unmapped olduğunu varsayıp atlar
- Bir seviye 2 PTE, 512 sayfalık aralığı kapsar
- Normal bir
kbase_va_regioniçinde eşlenmiş sanal adresler her zaman bölgenin başlangıcından itibaren kesintisizdir ve ortada gap bulunmaz; bu yüzden bu atlama davranışı güvenlidir - CVE-2023-6241 exploit’i, eşlemeler arasında unmapped gap oluşturduktan sonra shrink başlangıç noktasını gap’in içine yerleştirir
kbase_mmu_teardown_pgd_pages, invalid seviye 2 PTE ile karşılaşınca 512 sayfayı atlar; ancak bunun arkasındaki bazı adresler gerçekte eşlenmiş olabilir- Hatalı şekilde atlanan GPU adresleri, backing page serbest bırakıldıktan sonra da ilgili fiziksel sayfaya erişimi sürdürür
Kernel kodu çalıştırmaya giden süreç
- JIT bölgesi serbest bırakıldığında backing page’ler iade edilir; ancak hatalı şekilde kalan GPU eşlemesi, serbest bırakılan sayfalara erişmeye devam edebilir
- Serbest bırakılmış backing page daha sonra başka kernel sayfaları için yeniden kullanılabilir
- Kullanılan tekniklerden biri, serbest bırakılmış backing page’in GPU
kbase_context’inin PGD(page table global directory)’si olarak yeniden kullanılmasını sağlamaktır - Mali driver’daki backing page ayırma işlemi hiyerarşik olarak yapılır
- Önce mevcut
kbase_context’inkbase_mem_pool’undan sayfa alınır - Yetersiz kalırsa
pool->next_poolkullanılır - Bu da yetersiz kalırsa kernel buddy allocator üzerinden doğrudan sayfa ayrılır
- Önce mevcut
pool->next_pool, Mali driver tarafından yönetilen ve tümkbase_context’lerin paylaştığı bir bellek havuzudur; GPU bağlamının PGD ayırmalarında da kullanılır- Serbest bırakılmış sayfa PGD olarak yeniden kullanılırsa, geride kalan GPU adresiyle bu PGD GPU üzerinden tekrar yazılabilir
- PGD yeniden yazıldığında, keyfi kernel belleği ve kernel kodu GPU’ya eşlenebilir
- Bu durumda kernel kodu yeniden yazılarak keyfi kernel kodu çalıştırmak mümkün olur; kernel verileri okunup yazılarak process credential değişimi ve SELinux’un devre dışı bırakılması da yapılabilir
- Pixel 8 için exploit ve yapılandırma notları GitHub Security Lab deposunda yayımlandı
MTE’nin neden atlatılabildiği
- Bu exploit akışında MTE’ye özel ayrı bir atlatma adımı gerekmez
- MTE, pointer’ın işaret ettiği bellek bloğunun tag’inin eşleşip eşleşmediğini denetleyerek hatalı dereference işlemlerini yakalayan bir özelliktir
- CVE-2023-6241’in tetiklendiği anda
pagesdizisi ile GPU eşlemesi arasında tutarsızlık oluşur; ancak her birine ayrı bakıldığında invalid entry bulunmaz kbase_mmu_teardown_pgd_pagesGPU eşleme kaldırmayı atladığında, serbest bırakılmış bellek sayfasının fiziksel adresi GPU sayfa tablosunda kalır- GPU bu serbest bırakılmış sayfaya erişirken fiziksel adrese doğrudan eriştiği için pointer dereference denetiminden geçmez
- MTE’nin GPU bellek erişimine etkisi de kesin değildir
- Sonuç olarak bu bug, bir yardımcı işlemci olan GPU’nun fiziksel belleğe doğrudan eriştiği yolu kullanarak MTE korumasını atlatır
MTE sonrasında da kalan saldırı yüzeyi
- CVE-2023-6241, kernel MTE etkinleştirilmiş Pixel 8’de bile tek bir bug ile keyfi kernel kodu çalıştırmaya ulaşılabildiğini gösteriyor
- MTE, bellek bozulması azaltmalarında önemli bir ilerlemedir ve birçok bellek bozulması zafiyetini istismar edilemez hâle getirebilir; ancak her derde deva bir savunma değildir
- Bu vakada GPU, fiziksel belleğe doğrudan erişerek MTE’yi atlatır
- CPU tarafındaki donanım ve yazılım azaltma önlemleri arttıkça, yardımcı işlemciler ve onların kernel driver’ları güçlü bir saldırı yüzeyi olmaya devam edebilir
1 yorum
Hacker News yorumları
Buradaki kilit nokta, GPU'nun uzun zamandır Android’in baş ağrılarından biri olması.
GPU’nun AP’ye çok güçlü erişim yetkileri var; bu da öne konan hafifletmeleri fiilen aşabilmesini sağlıyor. Sürücünün eşleme kodundaki hatalar güçlü saldırı primitiflerine dönüşüyor ve gerçek dünyadaki exploit’lerde de tekrar tekrar kötüye kullanıldı. Sonuçta mimari yeniden tasarlanana kadar çok şeyin değişmesi zor görünüyor.
Bu zafiyette ilginç olan, Arm Mali GPU’nun bellek yönetim birimindeki mantıksal hata olması ve Memory Tagging Extension’ı aşabilmesi.
Ancak yazının geri kalanı, asıl nedenin bir yarış durumu olduğunu ve use-after-free’in bunun sonucu olduğunu açıklıyor gibi görünüyor.
Mart güncellemesinden önceki GrapheneOS kurulumları da etkilenmiş olabilir miydi?
Zaman zaman yayımlanmadan önce AOSP güvenlik yama seviyelerini benimser veya henüz herkese açık olmayan AOSP ya da kernel kaynaklarındaki güvenlik düzeltmelerini de backport eder.
Düzeltme: Dikkate almayın. Yakın tarihli GrapheneOS blogundaki “MTE’nin tüm sistem uygulamalarına da uygulanmasıyla ilgili bir sorun bulduk” yazısıyla karıştırmışım. GrapheneOS, 2024030600 sürümünde “tam 2024-03-05 güvenlik yama seviyesini” aldığına göre bu yama da dahil edilmiş görünüyor.
Olasılıksal Arm MTE bellek güvenliği, deterministik CHERI donanımına giden yolda bir basamak taşıdır: https://saaramar.github.io/memory_safety_blogpost_2022/ ve https://news.ycombinator.com/item?id=39668053
Doğru hafifletme, birincil saldırı ilkelini, yani hatanın kök nedenini hedeflemelidir. Donanım çözümleri arasında CHERI (Morello, CheriIoT) ve MTE; yazılım hafifletmeleri arasında kalloc_type+dataPAC, AUTOSLAB, Firebloom, GuardedMemcpy, CastGuard ve saldırı yüzeyinin azaltılması; güvenli programlama dilleri arasında ise Rust ve Swift vardır. MTE ile CHERI birbirini iyi tamamlar ve bu alandaki hataları kök nedenlerinde ortadan kaldırmaya yardımcı olur. MSR, MSRC ve Azure Silicon, CHERI’yi en küçük RISC-V çekirdeği belirtimi olan RISC-V32E’ye kadar küçültme yönünü destekledi.
Microsoft Research, IoT cihazları için CHERI donanım/yazılım yığınını açık kaynak olarak yayımladı: https://msrc.microsoft.com/blog/2023/02/first-steps-in-cheri...
CHERI tabanlı mikrodenetleyici, komut kümesi mimarisi (ISA), uygulama ikili arayüzü (ABI), izolasyon modeli ve yazılım yığınının çekirdek kısmı birlikte tasarlandığında çok güçlü güvenlik garantileri elde etmeyi amaçlar. Bu mikrodenetleyici, CHERI-ISA özellikleriyle uzamsal güvenliğin deterministik hafifletilmesini; yük bariyerleri, sıfırlama, geri kazanım ve 1 bitlik bilgi akışı denetimiyle heap ve bölmeler arası stack zamansal güvenliğinin deterministik hafifletilmesini; ek CHERI-ISA özellikleri ve küçük bir monitörle ince taneli bölmelendirmeyi sağlar.
David Chisnall, Cambridge Üniversitesi, https://lobste.rs/s/gnjx2n/c_can_be_memory_safe#c_9ohzku via https://eclypsium.com/blog/a-faster-path-to-memory-safety-ch...
“Çeşitli güvenilir bilişim tabanlarında yer alan yaklaşık 13 milyar satır açık kaynak C/C++ kodu var; tescilli kodlar dahil edilince bu daha da büyüyor. Bugün herkes C/C++ yazmayı bıraksa ve tüm yazılım mühendisleri eski kodu güvenli bir dille yeniden yazmaya odaklansa bile, her şeyi değiştirmek 5 ila 10 yıl sürer; uzun süredir doğrulanmış kodu, güvenli dillerin izin verdiği kalıplara uyan farklı algoritmalar ve veri yapıları gerektiren yeni kodla değiştirirken çok sayıda mantık hatası doğması da çok olasıdır.”
“Yeniden yazma yapılmadan yalnızca C/C++ kodu yazmayı bırakırsak, tipik kod değiştirme hızında güvenilir bilişim tabanının tamamen güvenli hale gelmesi yaklaşık 50 yıl alır. Herkes C/C++’ı bırakma konusunda anlaşmazsa en az 100 yıl sürer.”
“Buna karşılık büyük CPU üreticileri 5 yıl içinde CHERI CPU’lar çıkarırsa, programcılar davranışlarını değiştirmese bile bugünden itibaren 15 yıl içinde makinelerin çoğu, özellikle de yüksek değerli makineler, bellek güvenliğine sahip olur.”
İlki Sonata sistemi: https://github.com/lowRISC/sonata-system. FPGA ile çeşitli çevre birimleri ve header’lara sahip özel bir PCB’den oluşuyor. PCB tasarımı tamamlandı ve Mouser üzerinden temin edilebilir olacak; kart yerleşimi de açık kaynak olduğundan isterseniz kendiniz de monte edebilirsiniz. Şu anda FPGA için RTL üzerinde çalışılıyor. Tamamlandığında belgeleri ve araçlarıyla birlikte CHERIoT tabanlı mikrodenetleyici tarzı bir sisteme sahip olacaksınız.
Ayrıca Sonata ile OpenTitan Earl Grey güven kökünü birleştiren Symphony sistemini de geliştiriyorlar: https://github.com/lowRISC/symphony-system
Üstelik en son baktığımda CHERI sağlam değildi. Üzerinde yine de bellek hataları yazılabiliyordu; bu artık düzeltildi mi?
Sadece bisiklet kulübesi tartışmaları bile o kadar sürecek gibi.
Bu exploit’in Rust dahil çoğu dille yazılabileceğini düşünüyorum.
Donanım o kadar mı kötü? Aman Tanrım...
Bu yaklaşımın mümkün olmasının nedeni, GPU’nun CPU gibi nispeten doğrudan donanım erişimine izin vermemesidir.
Harika bir araştırma ve yazı; GitHub blogunda yayımlanmış olması biraz şaşırtıcı ama sevindirici
GitHub’ın bu tür araştırmalar yapmasının “iş gerekçesinin” ne olduğunu bilen var mı? Mutlaka bir iş gerekçesi olması gerektiğini söylemiyorum, ama burada görünce biraz şaşırdım
Bu araştırma işlevi GitHub Security Lab’e dönüştü. Semmle, CodeQL’i geliştirdi; bugün GitHub tarafından sunuluyor (https://docs.github.com/en/code-security/code-scanning/intro...). GitHub ve Microsoft, CodeQL’i “derin güvenlik içgörüleri” ile ilişkilendirmek istiyor (https://www.microsoft.com/en-us/security/blog/2023/11/02/ann...)
Bu yüzden böyle özgün güvenlik araştırmalarını finanse etmeye devam ediyorlar; sektördeki güvenlik uygulayıcıları da bundan memnun
GitHub uygulaması da var ve o uygulamanın güvenliği GitHub’ın kapsamı dışında değil. Bir saldırgan telefona gizlenen bir uygulama yükleyebilirse kullanıcıymış gibi pek çok şey yapabilir. GitHub’da etkisi olan biri söz konusuysa zarar oldukça büyük olabilir; dolayısıyla bu tür açıkları bulmak GitHub’ın da yararına
Bu nedenle MTE kullanarak sandboxing için Arm donanımındaki güvenlik özelliklerini kontrol edip doğrulamakla ilgileniyor olabilirler
İlk bakışta GitHub adlı ürün için Android güvenlik uzmanlarına mutlaka ihtiyaç yok. Ama uzun vadede potansiyel getirileri var
[0]: https://en.wikipedia.org/wiki/Basic_research
GPU’su çok az olan ya da hiç olmayan CPU’lar ve telefonlar yapıp bunlara iş telefonu diyen örneklerin hâlâ olmaması şaşırtıcı
Güvenlik, maliyet ve güç tüketimi açısından avantajları açık görünüyor