hfsplus slab OOB write (CVE-2025-0927)¶
HFS+ B-tree key okuma path'indeki eksik bir bounds check, crafted ve mount edilmiş bir HFS+ image'in attacker kontrollü bir key'i
kmalloc-1kslab buffer'ının ötesine yazmasına izin verir — desktop automount üzerinden erişilebilen bir slab out-of-bounds write.
Mechanism¶
HFS+, catalog/attribute kayıtlarını disk üzerindeki B-tree node'larında saklar. Kernel bir record key'ini okuduğunda, on-disk node'dan alınan bir length'i sabit boyutlu bir kernel buffer'ına kopyalar ama o length'i allocate ettiği buffer'a karşı asla doğrulamaz.
Note
hfs_find_init() key buffer'ını kmalloc(tree->max_key_len * 2 + 4, GFP_KERNEL) olarak allocate eder. Attribute B-tree için max_key_len = 0x10a'dır, bu da kmalloc-1k'ye düşen 0x218 byte'lık bir allocation verir. hfs_bnode_read_key() (fs/hfsplus/bnode.c içinde) ardından per-record key length'ini doğrudan node'dan okur (key_len = hfs_bnode_read_u16(node, off) + 2) ve o kadar byte kopyalar. Hiçbir şey record'un u16 key length'ini max_key_len'e clamp etmez, dolayısıyla aşırı büyük bir on-disk değer slab object'ini overflow eder.
Warning
Tetikleyici mount edilmiş bir filesystem image'dir. İlginç olan açık, desktop automount'tur: udisks2 + polkit bir console user'ın initial namespace'te açıkça CAP_SYS_ADMIN tutmadan removable media mount etmesine izin verir.
Kavramsal slab görünümü — buffer kmalloc(max_key_len * 2 + 4) ile boyutlanır ama kopya 0x218'e değil node'dan okunan değere göre yapılır (boyutlar/adresler kernel'e göre değişir):
kmalloc-1k slab object (key buffer, 0x218 byte allocate edildi)
+-----------------------------------------------+········ komşu slab object'ler ········
| key_len (beklenen <= max_key_len) | | victim object | ...
| kopyalanan key bytes ----------------->| | |
+-----------------------------------------------+········+----------------+···········
^ ^
| |
allocation sınırı | | OOB write buradan başlar
(on-disk key_len clamp edilmediğinde)
clamp YOK: key_len = hfs_bnode_read_u16(node, off) + 2 → attacker-controlled, > 0x218 olabilir
Walkthrough¶
Attila Szász tarafından raporlandı (SSD üzerinden açıklandı), Ubuntu 22.04 (kernel 6.5.0-18-generic) üzerinde çalışan bir PoC ile:
- Bir HFS+ image craft et;
__hfs_brec_findcheck'lerini bypass etmek için attribute B-tree root'unu null yap. - Record key-length field'ı
0x218byte'lık allocation'ı aşan bir node craft et. - Image'i mount et (ya da automount mount etsin diye media tak). Attribute insertion sırasında,
hfs_brec_insert→hfs_bnode_read_key()aşırı büyük key'i kopyalar ve kmalloc-1k object'ini overflow eder.
Overflow primitive'dir; onu LPE'ye dönüştürmek standart slab-overflow exploitation'ı izler (örn. bir victim object'e karşı cross-cache — SSD kmalloc-cg-1k'yi tartışır).
Detection¶
KASAN, hfs_bnode_read_key/hfs_bnode_read içinde bir slab-out-of-bounds write raporlar. Policy seviyesinde, güvenilmeyen bir HFS+ image'in automount'u gözlemlenebilir olaydır.
Mitigation¶
Upstream başta bir CVE'yi reddetti ("corrupt-image filesystem bug'ları yalnızca initial userns'te CAP_SYS_ADMIN ile mount edilebilen filesystem'ler için bir CVE değildir"), ama distro'lar automount yüzünden yine de patch'lediler. Ubuntu düzeltmeleri arasında noble 6.8.0-54.56, jammy 5.15.0-133.144, focal 5.4.0-208.228, bionic 4.15.0-234.246 var. Patch olmadan: hfsplus/hfs modüllerini blocklist'le ve udisks2/polkit automount'unu bir allow-list ile kısıtla.