Elastic objects¶
Allocation size'ı ve in-band length field'ı attacker-controlled olan kernel object'leri; bu yüzden herhangi bir kmalloc cache'ine spray edilebilir ve length'leri bozularak out-of-bounds read'e dönüştürülebilir.
Mechanism¶
Note
Bir elastic object (Chen, Lin, Xing — ACM CCS 2020, "A Systematic Study of Elastic Objects in Kernel Exploitation"), elastik bir kernel buffer'ının boyutunu kontrol eden bir length field içerir; kernel daha sonra o buffer'ı okurken kaç byte okuyup yazacağına karar vermek için bu length'e güvenir. İki yapısal biçim vardır: buffer object'in içine gömülüdür (sondaki flexible array), ya da object harici bir buffer'a pointer tutar.
İki özellik onları güçlü kılar. (1) Allocation size kullanıcı-kontrollü bir length
tarafından sürüldüğü için, aynı object tipi farklı kmalloc-N cache'lerine
yönlendirilebilir; böylece keyfi boyuttaki freed bir victim'i eşleştirip reclaim eder —
universal heap spray. (2) In-band length field'ını bir OOB write ile bozmak, sonraki bir
read'i komşu kernel memory'sinin over-read'ine çevirir: bir function pointer'ı leak etmek
KASLR'ı kırar, freed bir slot'u over-read etmek heap cookie'sini sızdırır, ve object bir
pointer tutuyorsa over-read arbitrary read'e yaklaşır.
Paper'ın keşif aracı ELOISE (ExploitabLe Object dIScovEry). 40 güvenlik açığı arasında elastic object'ler 27/40'ında KASLR/cookie disclosure'ı ve 8/40'ında arbitrary read'i mümkün kıldı.
Walkthrough¶
Kanonik elastic object, System V message header'ı struct msg_msg'dir:
struct msg_msg {
struct list_head m_list;
long m_type;
size_t m_ts; /* message text size = elastic LENGTH field */
struct msg_msgseg *next; /* pointer to next data segment */
void *security;
/* message data follows inline */
};
msgsnd() -> load_msg() -> alloc_msg(), ilk chunk'ı min(len, DATALEN_MSG) olarak
boyutlandırır; DATALEN_MSG = PAGE_SIZE - sizeof(struct msg_msg) = 0xfd0'dır, yani message
length'ini seçmek msg_msg'i seçilen bir kmalloc-N'e spray ederek freed bir victim'i
reclaim eder. Length-corruption read:
- Bir
msg_msg'i bir victim'e bitişik/onunla örtüşecek şekilde yerleştir ve kuyruğa al (henüz receive etme). m_ts'i ayrı bir OOB write / UAF ile daha büyük bir değere boz.msgrcv()çağır — kernelm_tsbyte'ı userland'e geri kopyalar, gerçek buffer'ın ötesine geçerek komşu kernel memory'sini okur (OOB read / info leak).- Corruption ayrıca
next'i de set ediyorsa, segment-traversal döngüsü attacker-controlled pointer'ı takip ederek neredeyse-arbitrary bir read yapar.
Warning
Paper'ın kendi işlenmiş örneği xfrm_replay_state_esn'dir (length field'ı bmp_len,
recvmsg ile geri okunur); bu, komşu bir object'in f_op'una (ext4_file_operations)
over-read yaparak KASLR'ı kırar. msg_msg, paper'ın elastic-object tablosunda listelenir;
yukarıdaki m_ts/msgrcv mekanikleri kernel-doğru writeup'lardan alınmıştır.
Mitigation¶
ELOISE, elastic object'leri bir __GFP_ISOLATE flag'i aracılığıyla özel shadow cache'lere
(örn. kmalloc-isolated-N) izole etmeyi önerir; böylece sıradan bir cache'teki bir bug bir
elastic object'i victim'inin bitişiğine yerleştiremez (~%0.19 overhead). Genel slab freelist
hardening/randomization da deterministik bitişikliği azaltır.