Skip to content

Kernel Address Space Layout Randomization

Kernel image'ının yükleme adresini (ve memory region base'lerini) boot başına bir kez randomize et ki saldırganlar kernel kodunun ve data'sının konumunu hardcode edemesin.

Mechanism

Neden çalışır

Klasik kernel exploit'leri control flow'u sabit bir kernel adresine yönlendirir — bir ROP gadget'ına, commit_creds'e ya da bir set_memory_x page'ine. Bu yalnızca saldırgan kernel text'in nerede yaşadığını biliyorsa çalışır; bu da randomize edilmemiş bir kernel'de build-time bir sabittir (örn. 0xffffffff81000000).

KASLR (CONFIG_RANDOMIZE_BASE) bu varsayımı kırar: boot'ta kernel decompressor'ı rastgele bir offset (yani slide) seçer ve kernel image'ını base + slide'a relocate eder. Kurmaya çalıştığı invariant şudur: herhangi bir kernel sembolünün adresi boot başına bir sırdır, yani tahmini ya da eski bir adresle inşa edilmiş bir payload yanlış page'e düşer ve temiz bir privilege escalation yerine başarısız olur (tipik olarak bir crash).

x86-64'te fiziksel ve virtual yerleşimler ayrı ayrı randomize edilir; kernel virtual base'i, yaklaşık 9 bit text-randomization entropy'si veren bir pencereden çekilir ve slide, kernel'in large-page mapping'inin 2 MB granularity'sinde uygulanır. CONFIG_RANDOMIZE_MEMORY ek olarak direct (physmap) mapping, vmalloc ve vmemmap bölgelerinin base'lerini randomize eder. Entropy RDRAND/RDTSC'den (ya da fallback olarak i8254 timer'dan) toplanır veya EFI stub üzerinden boot edilirken firmware tarafından EFI_RNG_PROTOCOL / /chosen/kaslr-seed device-tree property'si aracılığıyla sağlanır.

Slide bir kez seçilip asla yeniden atılmadığı için KASLR ancak tek bir kernel adresinin gizliliği kadar güçlüdür — güvenilir herhangi bir leak onu tamamen çökertir.

Userspace ASLR'den farkı temel iki noktadadır: KASLR slide'ı her process için değil, boot başına bir kez seçilir (re-randomize edilmez) ve user mapping'leri değil kernel text/data ile physmap/vmalloc/vmemmap region'larını hedefler.

Walkthrough

1. KASLR'nin compile edildiğini ve aktif olduğunu doğrula.

$ grep CONFIG_RANDOMIZE_BASE /boot/config-$(uname -r)
CONFIG_RANDOMIZE_BASE=y
$ grep CONFIG_RANDOMIZE_MEMORY /boot/config-$(uname -r)
CONFIG_RANDOMIZE_MEMORY=y

2. Boot başına slide'ı gözlemle. Yetkilerle, kernel text'in runtime base'i reboot'lar arasında farklılaşır:

# boot A:
$ sudo grep ' _text$' /proc/kallsyms
ffffffff8a800000 T _text
# boot B (same kernel, rebooted):
$ sudo grep ' _text$' /proc/kallsyms
ffffffff9d200000 T _text

# slide = runtime _text - link-time base (CONFIG_PHYSICAL_START region)

3. Debugging için devre dışı bırak (yalnızca test makineleri). KASLR kernel command line'da toggle edilir:

# /etc/default/grub
GRUB_CMDLINE_LINUX="... nokaslr"     # disable
# (default, or "kaslr") leaves it enabled

Tek bir leak onu yener; KASLR isolation değildir

KASLR çıtayı yükseltir ama bir kernel adresi elde eden bir exploit'i durdurmaz. Tek bir info leak — kısıtlanmamışsa /proc/kallsyms, bir uninitialized-memory disclosure'ı, dmesg ya da bir microarchitectural oracle — slide'ı verir ve tüm image'ı derandomize eder. KASLR, kptr-restrict, kallsyms-address-restriction ve dmesg-restrict gibi leak bastıran mitigation'larla eşleştirilmelidir.

Detection

Çalışan config'te CONFIG_RANDOMIZE_BASE=y, cmdline'da nokaslr'nin yokluğu (cat /proc/cmdline) ve reboot'lar arasında değişen bir kernel _text base'i — hepsi KASLR'nin çalıştığına işaret eder.

Mitigation

(Residual risk / bypass.) KASLR, herhangi bir adres disclosure'ına (proc-kallsyms-symbol-address-leak), re-randomization'ın ucuz olduğu yerde brute force'a (aslr-brute-force) ve translation yapılarını yoklayan side channel'lara (entrybleed-kpti-kaslr-bypass) yenilir. function-granular-kaslr gibi daha ince taneli varyantlar, tek bir text leak'in değerini azaltır.

References