DirtyCred file exploitation¶
Free a writable kernel
struct fileobject after its write-permission check has passed, then let the kernel reclaim the freed slot with a privileged read-onlyfile— so a pending write lands in the privileged file. Data-only privilege escalation that needs no control-flow hijack or KASLR leak. (Herestruct fileis a file object, not a credential object; DirtyCred's broader class also targets thestruct credcredential object, covered separately — this note is thefilevariant.)
Mechanism¶
Note
DirtyCred (Lin, Wu, Xing — ACM CCS 2022), object'lerin içeriğini bozmak yerine
kernel credential object'lerini heap reuse yoluyla takas ederek privilege yükseltir.
Hedeflenen object'ler cred ve file'dır (makale inode'u da sayar ama allocation
esnekliği eksikliği nedeniyle dışlar). Bir dosya açıldıktan sonra kernel,
credential/permission bilgisini inode'dan ayırır ve struct file'a iliştirir;
file object'i read/write izin bit'lerini (f_mode) taşır ve arkadaki credential'lara
index'ler. Exploit'in iddia ettiği üç özellik: data-only (KASLR/heap-leak gerekmez),
universal (kernel/mimari bağımsız) ve effective (upstream mitigation'ları
bypass eder).
File variant'ı bir heap bug'ını (UAF, double-free, type confusion) şu yeteneğe çevirir:
write-permission kontrolü zaten geçmiş yazılabilir bir file'ı free etmek, sonra
o slab slot'unu privileged read-only bir file ile reclaim etmek; böylece bekleyen
bir write privileged dosyaya düşer. Hiçbir control flow değiştirilmediği ve hiçbir object
içeriği forge edilmediği için CFI, credential-integrity kontrolleri (örneğin Knox RKP)
ve type-tabanlı object isolation (AUTOSLAB, xMP) bunu durduramaz.
Permission kontrolü ile asıl data write arasındaki race window, bir kernel-pause primitive
ile genişletilir: userfaultfd, FUSE-destekli bir kaynak buffer veya — modern kernel'lerde
en sağlam yöntem — yarışan büyük bir write tarafından tutulan filesystem inode lock.
Walkthrough¶
Klasik gösterim (makale Figure 1) CVE-2021-4154'ü kullanır; bu, kullanımda olan bir
file object'ini free eden bir fs_context type confusion'dır. Referans exploit
(Markakd/CVE-2021-4154) inode-lock variant'ını userfaultfd olmadan kullanır:
// THREAD A: hold the inode lock with a slow, large write
int fd_big = open("/tmp/x", O_WRONLY);
write(fd_big, big_buf, 4UL*1024*1024*1024); // holds inode_lock ~dozens of seconds
// THREAD B: victim writable file object — open via a SYMLINK so the file lacks
// FMODE_ATOMIC_POS (avoids the __fdget_pos position-lock stall)
int fd = open("/tmp/x_symlink", O_WRONLY); // struct file allocated in filp_cache
write(fd, payload, len); // passes FMODE_WRITE check, then blocks
// on inode_lock — this is the race window
// THREAD C: during B's lock-wait, free B's struct file and reclaim the slot
trigger_fsconfig_uaf(); // CVE-2021-4154 frees B's struct file
int p = open("/etc/passwd", O_RDONLY); // reclaims the freed filp_cache slot
// THREAD A finishes -> releases inode_lock -> THREAD B's write lands in /etc/passwd
// payload e.g. "hacker:x:0:0:root:/:/bin/sh\n" -> a root account
Warning
struct file kendi özel slab cache'inde yaşar (filp_cache, sembol
filp_cachep); CVE-2021-4154 örneğinde bu object'ler kmalloc-192'ye düşer.
Yukarıdaki pseudo-code doğrulanmış adımları temsil eder, exploit'in birebir kopyası
değildir. f_mode/FMODE_WRITE/FMODE_ATOMIC_POS dışındaki alan adları standart
kernel bilgisidir, makaleden birebir değildir.
Beklenen sonuç: /etc/passwd'ye bir uid=0 satırı eklemek root bir login shell verir
(örneğin su hacker), ve bunu hiçbir kernel pointer leak'lemeden yaparak escalation'ı
gösterir.
Mitigation¶
Makale privilege-tabanlı isolation önerir: privileged object'leri (root cred,
yazılabilir file) vmalloc bölgesine yerleştirip unprivileged object'leri direct-mapped
kmalloc bölgesinde tutmak; böylece ikisi asla geri dönüştürülmüş page'leri paylaşmaz —
cross-cache page-reuse pivot'unu etkisizleştirir. PoC patch'i (CONFIG_CRED_ISOLATION)
write-mode dosyaları vzalloc() üzerinden yönlendirir ve kvfree() ile free eder. Upstream
bunu benimsemedi, ama ilgili hardening eğilimi — 5.14'ten beri accounted ve unaccounted
object'ler için ayrı slab cache'ler (kmalloc-cg-*) — spray yüzeyini daraltır.