Hashed kernel pointers (%p hashing)¶
Linux 4.15'ten beri
%pprintf specifier'ı kernel pointer'larını SipHash ile hash'ler; böylece ham kernel address'leri log, sysfs veya procfs üzerinden leak olmaz; gerçek bir address yazmak için%pxkullanılmalıdır.
Mechanism¶
Note
Invariant: süssüz herhangi bir %p artık gerçek bir kernel address
yaymaz. lib/vsprintf.c, düz %p'yi pointer değerini rastgele üretilmiş,
per-boot bir key (ptr_key) ile key'lenen SipHash üzerinden geçiren
ptr_to_id() üzerinden yönlendirir. Pointer yerine 32-bit sonuç yazılır,
böylece kernel çıktısını okuyan bir attacker kernel memory layout'unu geri
kazanamaz (bir info-leak / KASLR-bypass primitive'ini yenerek). Gerçek
address'i yazmak artık açık, greppable bir specifier (%px) gerektirir.
Tobin C. Harding'in commit'inden (Kees Cook tarafından önerildi) gelen
motivasyon, süssüz %p ile address yazan kabaca 14.000 site olmasıydı. Her birini
audit etmek yerine default değiştirildi, böylece %p güvenli oldu ve gerçekten ham
bir address'e ihtiyacı olan kod %px ile opt-in yapıyor.
64-bit sistemlerde hash'in üst 32 bit'i sıfırlanır. Key'i seed etmek için yeterli
randomness mevcut olmadan önce, %p tahmin edilebilir bir değer yerine
(ptrval) placeholder'ını yazar.
Warning
%px, %lx ile fonksiyonel olarak eşdeğerdir ve ham address'i hashing
olmadan yazar. Onu yalnızca değerin hassas kernel memory layout'unu
unprivileged okuyuculara expose edemeyeceğini doğruladıktan sonra kullan. %pK,
kptr_restrict sysctl'i ile gate'lenmiş ayrı bir mekanizmadır ve yalnızca
userspace-okunabilir dosyalar (procfs/sysfs) için tasarlanmıştır, kernel
log'ları için değil.
Walkthrough¶
Observe hashing in dmesg
Düz bir %p yazımı, bir address değil boot başına sabit bir hash verir:
Aynı değer %px ile yazılsa gerçek kernel virtual address'ini gösterirdi
(ör. ffffffff81a0c2e0).
Hashing'i debugging için, her %p'nin address'i değiştirmeden yazmasını sağlayan
belgelenmiş kernel parametresiyle boot ederek devre dışı bırak:
no_hash_pointers ile reboot'tan sonra %p çıktısı %px çıktısıyla eşleşir.
Parametre yalnızca debugging için tasarlanmıştır ve kernel'in artık address leak
ettiğine dair bir warning yazar.
Detection¶
Bir %p değerini iki boot arasında karşılaştır: hashing aktifse yazılan değer her
boot'ta değişir (yeni rastgele ptr_key); makul bir ffffffff... kernel address'i
olan bir değer %px, no_hash_pointers veya weak-hash debug build'ini gösterir.
Mitigation¶
%p hashing, ASLR bypass'larını besleyen pointer leak'lerine karşı bir
defense-in-depth önlemidir; kptr_restrict,
dmesg_restrict ve
kallsyms address restriction'ı tamamlar. Kasıtlı
%px kullanımı veya diğer side channel'lar üzerinden leak'leri durdurmaz — bkz.
info-leak / pointer-leak / ASLR bypass.