Strict kernel RWX (no W+X mappings)¶
Kernel space'te W^X'i zorunlu kılar: text/rodata read-only map'lenir, tüm data non-executable map'lenir, böylece hiçbir kernel page aynı anda writable ve executable olmaz.
Mechanism¶
CONFIG_STRICT_KERNEL_RWX ve CONFIG_STRICT_MODULE_RWX, kernel'in kendi memory
region'larına ayrı, minimal permission'lar uygulamasını sağlar: kernel/module
text'i read-only + executable (RO+X) olur, rodata read-only + non-exec
olur ve sıradan data read-write + non-executable (RW+NX) olur. Aynı prensip
module text/rodata'sına ve diğer executable region'lara (JIT page'leri vb.) uzanır.
Neden işe yarar
Code-injection ve birçok code-reuse kurulumu, hem writable (instruction'ları yerleştirmek ya da yeniden yazmak için) hem executable (onları çalıştırmak için) bir page'e ihtiyaç duyar. Kernel dokümantasyonu amacı doğrudan belirtir: code writable değildir, data executable değildir ve read-only data ne writable ne executable'dır. Bu, ring 0'a uygulanan W^X invariant'ıdır ("write XOR execute"): her mapping için W ve X bit'leri asla birlikte set edilmez. Bir saldırgan bir kernel write primitive'i elde ederse, RO+X text mevcut code'u yerinde patch'leyemeyeceği anlamına gelir; RW+NX data ise yazabileceği bir buffer'a branch edilip onun execute edilemeyeceği anlamına gelir. Koruma yapısaldır — belirli bir exploit'i tespit etmek yerine yeteneği kaldırır — dolayısıyla tüm "kernel memory'ye yaz, sonra onu execute et" saldırı sınıfı için çıtayı yükseltir ve düşmanları bunun yerine saf ROP/JOP'a ya da page-table manipulation'a iter.
Permission'lar architecture set_memory_ro/_rw/_x/_nx API'si üzerinden kurulur
(module'ler için, kernel/module/strict_rwx.c'deki module_enable_* helper'ları,
örn. module_enable_text_rox). Kernel invariant'ı runtime'da, bir W+X mapping
check'i gerçekleştiren page-table dumper'ı (ptdump) üzerinden doğrulayabilir.
Walkthrough¶
Seçeneklerin etkin olduğunu doğrula:
grep -E 'STRICT_(KERNEL|MODULE)_RWX' /boot/config-$(uname -r)
# CONFIG_STRICT_KERNEL_RWX=y
# CONFIG_STRICT_MODULE_RWX=y
Boot'ta W+X self-check'i çalıştıran kernel'lerde, dmesg sonucu raporlar:
ptdump üzerinden page-table permission'larını incelemek
CONFIG_PTDUMP_DEBUGFS (eskiden CONFIG_X86_PTDUMP / arm karşılıkları) ve
debugfs mount edilmişken, kernel page table'larını açar:
mount -t debugfs none /sys/kernel/debug # if not already mounted
cat /sys/kernel/debug/kernel_page_tables # x86; arm64: kernel_page_tables
Her region kendi flag'lerini yazar. Sağlıklı çıktı, text aralıklarını
ro ... x ve data aralıklarını RW ... NX olarak gösterir — asla hem RW
hem executable olan bir aralık olmaz. Runtime checker ptdump_check_wx() bu
table'ları walk eder ve "Checked W+X mappings" verdict'ini üreten şeydir.
Uyarılar
- Self-modifying makineler için — instruction alternative'leri, breakpoint'ler, kprobe'lar — kernel'in update sırasında bir page'i geçici olarak writable yapıp sonra orijinal permission'ları geri yüklediği kısa, kontrollü istisnalar vardır. Bunlar dar pencerelerdir, kalıcı W+X mapping'leri değil.
- Çoğu architecture'da bu seçenekler zorla açıktır ve user-selectable değildir; help metni ve default'lar arch'a göre değişir.
Detection¶
Boot-time ptdump_check_wx() verdict'i ("Checked W+X mappings: passed") ve
/sys/kernel/debug/kernel_page_tables dump'ı, kalıcı W+X kernel page'i olmadığını
doğrulamanın kanonik yollarıdır. Bir failure çıktısı sorunlu aralıkları listeler.
Mitigation¶
Residual risk / nasıl bypass edildiği:
- Strict RWX code-reuse'u durdurmaz: RO+X text'e karşı ROP/JOP hâlâ çalışır, ki bu da CFI ve shadow stack'leri motive eder.
- Page table'ları edit edebilen bir saldırgan, writable bir page'i tekrar executable işaretleyip policy'yi aşağıdan bypass edebilir — bkz. kernel set-memory-x page-table attack ve bpf-jit-spray gibi JIT-region suistimali.
- Data-execution prevention (no-execute-data-execution-prevention.md), grsecurity/PaX atası (pax-kernexec.md), post-init read-only data (read-only-after-init.md) ve module-loading integrity'sinin (module-signature-enforcement.md) yanında defense-in-depth'in bir katmanıdır.
References¶
- Linux kernel docs, "Kernel Self-Protection" (Executable Memory —
CONFIG_STRICT_KERNEL_RWX/CONFIG_STRICT_MODULE_RWX): https://docs.kernel.org/security/self-protection.html - Linux Kernel Driver DataBase,
CONFIG_STRICT_KERNEL_RWX: https://cateee.net/lkddb/web-lkddb/STRICT_KERNEL_RWX.html - Linux Kernel Driver DataBase,
CONFIG_STRICT_MODULE_RWX: https://cateee.net/lkddb/web-lkddb/STRICT_MODULE_RWX.html