kallsyms address restriction¶
/proc/kallsyms(ve/proc/modules) tarafından export edilen runtime adresleriniCAP_SYSLOGvekptr_restrictarkasına al; böylece unprivileged okuyucular symbol isimlerini, adresleri sıfırlanmış halde görür.
Mechanism¶
Neden çalışır
/proc/kallsyms, her kernel ve module sembolünü <address> <type> <name>
formatında canlı virtual address'iyle listeler. KASLR kernel text base'ini
boot başına yalnızca bir kez randomize ettiği için tek bir gerçek symbol adresi
tüm slide'ı geri kazandırır ve commit_creds / prepare_kernel_cred gibi
privesc gadget'larını konumlandırır. Bu yüzden ham adresleri herhangi bir
kullanıcıya export etmek KASLR'yi tamamen yener.
kallsyms address restriction şu invariant'ı zorunlu kılar: symbol→address
haritası privileged'dir; unprivileged bir okuyucu isimleri görebilir ama adres
olarak 0 görmek zorundadır. Adresler %pK specifier'ı ve
kallsyms_show_value(cred) görünürlük predicate'i ile basılır; bu predicate
kernel.kptr_restrict'i çağıranın capability'leriyle birleştirir:
kptr_restrict = 0: non-root bir okuyucu0alır, ama root gerçek adresleri görür (birçok distro'da default, çünkü isimlerin okunabilir kalması gerekir).kptr_restrict = 1: adresler yalnızcaCAP_SYSLOG'a sahip veeuid==ruid, egid==rgidolan çağıranlara gösterilir (örn. root ya dasudoile çalışan process'ler); privilege separation ile açılan (effective/real credential'ları uyuşmayan) bir processCAP_SYSLOGtaşısa bile0görür.kptr_restrict = 2: adresler herkes için, root dahil, sıfırlanır.
Kritik olan, predicate'in open()'da değil, read() anında okuyan task'ın
credential'larına karşı değerlendirilmesidir; yani dosyayı root olarak açıp
descriptor'ı adres sızdırmak için unprivileged bir process'e veremezsin. Aynı
kallsyms_show_value() gate'i /proc/modules'ü ve symbol taşıyan birkaç başka
interface'i de kapsar.
Walkthrough¶
1. Privileged ve unprivileged okumaları karşılaştır.
$ id -u
1000
$ cat /proc/sys/kernel/kptr_restrict
1
$ grep -E ' (commit_creds|prepare_kernel_cred)$' /proc/kallsyms
0000000000000000 T commit_creds
0000000000000000 T prepare_kernel_cred
$ sudo grep -E ' (commit_creds|prepare_kernel_cred)$' /proc/kallsyms
ffffffff8a0b1d40 T commit_creds
ffffffff8a0b1a90 T prepare_kernel_cred
Satır formatı, boşlukla ayrılmış üç field'dır: <address> <type> <name>. Yalnızca
adres sütunu redact edilir; symbol isimleri görünür kalır, böylece module
araçları çalışmaya devam eder.
2. Aynı restriction /proc/modules için de geçerli.
$ cat /proc/modules | head -1 # unprivileged
nf_tables 327680 1 - Live 0x0000000000000000
$ sudo head -1 /proc/modules # privileged
nf_tables 327680 1 - Live 0xffffffffc0a31000
3. Gate'i sıkılaştır. Address restriction kptr_restrict ile sürülür:
$ sudo sysctl -w kernel.kptr_restrict=1 # require CAP_SYSLOG to see addresses
$ sudo sysctl -w kernel.kptr_restrict=2 # zero addresses for everyone
Restriction adreslere yöneliktir, varlığa değil
Symbol isimleri her seviyede okunabilir kalır, yani bir fonksiyonun varlığı
asla gizlenmez — yalnızca konumu gizlenir. CAP_SYSLOG tutan bir process
(değer 1) yine de gerçek adresleri elde eder ve ilgisiz leak primitive'leri ya
da side channel'lar bu ayardan bağımsız olarak slide'ı geri kazanabilir.
Detection¶
/proc/kallsyms ve /proc/modules'ün adres sütununun unprivileged çağıranlar için
0 okuyup okumadığını gözlemle ve sysctl kernel.kptr_restrict'i kontrol et.
Hardening baseline'ları yaygın olarak kptr_restrict >= 1 ister.
Mitigation¶
(Residual risk / bypass.) Bu yalnızca kallsyms/modules symbol
interface'lerini korur. Slide hâlâ adres sızdıran diğer %pK/%px sink'leri,
dmesg, perf symbolization'ı, BPF ya da
../kernel/entrybleed-kpti-kaslr-bypass.md
gibi microarchitectural KASLR oracle'ları üzerinden geri kazanılabilir; ayrıca
bkz. ../kernel/proc-kallsyms-symbol-address-leak.md.
Bu, daha geniş kptr-restrict politikasının kallsyms'e özgü
uygulamasıdır.
References¶
- proc_kallsyms(5) — Linux manual page. — https://man7.org/linux/man-pages/man5/proc_kallsyms.5.html
- The Linux Kernel documentation. Documentation for /proc/sys/kernel/ — kptr_restrict. — https://docs.kernel.org/admin-guide/sysctl/kernel.html