Skip to content

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-1k slab 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:

  1. Bir HFS+ image craft et; __hfs_brec_find check'lerini bypass etmek için attribute B-tree root'unu null yap.
  2. Record key-length field'ı 0x218 byte'lık allocation'ı aşan bir node craft et.
  3. Image'i mount et (ya da automount mount etsin diye media tak). Attribute insertion sırasında, hfs_brec_inserthfs_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.

References