struct file spray¶
Çok sayıda file descriptor aç ve dedicated
filpslab cache'ini tazestruct fileobject'leriyle doldur; free edilmiş birstruct fileslot'unu reclaim ederek controlled ya da privileged bir file takas et (file-based DirtyCred'in arkasındaki çekirdek primitive).
Mechanism¶
Note
Her açık file, bir struct file tarafından desteklenir; bu da generic bir kmalloc-N
cache'inden değil, filp adlı dedicated bir slab cache'inden (filp_cachep) allocate
edilir — dolayısıyla reclaim, arbitrary bir heap object yerine başka bir struct file
allocation'ından gelmelidir. İlgili field'lar şunlardır: f_op (operation başına hangi
handler'ın çalışacağını seçen file_operations tablosuna pointer), f_mode (read/write
permission dahil access-mode bit'leri) ve f_count (refcount). Spray, bir struct file
üzerindeki bir UAF/double-free'yi istismar eder: vulnerable object'i free et, sonra free
edilmiş slot'u privileged bir target için bir struct file ile reclaim etmek üzere çok
sayıda open() çağrısı ver. !(file->f_mode & FMODE_WRITE) gibi bir permission check bir
noktada değerlendirildiği ama write handler (artık takas edilmiş) file'ı daha sonra çözdüğü
için, bir attacker check'i writable bir file üzerinde geçebilir ama altında privileged file'a
sahip olabilir.
Walkthrough¶
- Çok sayıda
open()çağrısıyla spray et — heropen(),filp_cachep'te yeni birstruct fileallocation'ı üretir:
for (int i = 0; i < N; i++)
fd[i] = open("/some/target", O_RDONLY); /* each = one fresh struct file */
Not: dup(), yeni bir struct file allocate etmez; yalnızca mevcut olanın f_count'unu
artırır, dolayısıyla bir spray primitive'i değildir.
2. UAF/double-free'yi tetikle, böylece vulnerable struct file filp_cachep'e geri free
edilsin.
3. Free edilmiş chunk'ı controlled / privileged bir file ile reclaim etmek için open()'ı
yeniden spray et (filp cache'i file ve socket işlemleriyle yoğun çalıştırılır, dolayısıyla
reclaim güvenilirdir).
4. Takası istismar et: reclaim edilmiş object'in f_mode'u (permission bit'leri) ve f_op'u
(operation handler'ları), önceki permission check'in validate ettiğinden farklıdır — write
zaten f_mode check'inden geçmişti ama altındaki struct file artık privileged bir file'a
işaret eder; bu da privileged bir write'ı (örn. /proc/sys/kernel/modprobe'a) ya da hijack
edilmiş bir file işlemini mümkün kılar.
Warning
struct file kendi cache'inde yaşar, dolayısıyla generic bir kmalloc spray'i onu reclaim
edemez — reclaim allocation'ının kendisi bir struct file olmalıdır (bir target file'ın
open'ı). Onu farklı bir object tipiyle reclaim etmek için bir page-level cross-cache adımı
gerekir.
Mitigation¶
- Dedicated
filp_cachep'in kendisi kısmî bir savunmadır — cross-type reclaim'i sınırlar. CONFIG_SLAB_FREELIST_HARDENED/CONFIG_SLAB_FREELIST_RANDOM, deterministik reclaim'i zorlaştırır.- DirtyCred-sınıfı mitigation'lar, privileged credential/file object'lerini izole eder (örn.
elevated
struct cred/struct file'ı ayıran virtual isolation).