Skip to content

bpf_probe_read arbitrary kernel memory read

Bir tracing BPF program'ı, attacker'ın seçtiği bir kernel address'iyle bpf_probe_read helper'ını çağırarak fault-safe şekilde arbitrary kernel memory okur ve bunu bir BPF map üzerinden dışarı sızdırır.

Mechanism

Note

Tracing BPF program'ları için (kprobes, tracepoints, perf events), bpf_probe_read bir kernel-space address'inden size byte'ı güvenli şekilde BPF kontrollü bir destination'a okur. "Güvenli" demek, erişim sırasında oluşan bir fault'un kernel'i oops'lamak yerine yakalanıp error olarak döndürülmesi demek — ama target address program tarafından kontrol edildiği için, bir tracing program'ı arbitrary kernel memory okuyup bunu (örneğin bir BPF map üzerinden) dışarı sızdırabilir, böylece KASLR'ı aşar ya da secret'ları döker. Kernel BPF design FAQ bunu doğrudan söylüyor: "Tracing bpf programs can read arbitrary memory with bpf_probe_read()."

Walkthrough

Helper prototype'ı (bpf-helpers(7)'ten):

long bpf_probe_read(void *dst, u32 size, const void *unsafe_ptr);
/* "For tracing programs, safely attempt to read size bytes from kernel
    space address unsafe_ptr and store the data in dst."
    Returns 0 on success, or a negative error on failure. */

Bir tracing program'ın içinde, seçilen bir kernel address'i okuyup userspace için saklayalım:

SEC("kprobe/some_func")
int probe(struct pt_regs *ctx) {
    char leak[64];
    bpf_probe_read(leak, sizeof(leak), (void *)TARGET_KERNEL_ADDR);
    bpf_map_update_elem(&out_map, &key, leak, BPF_ANY);  /* exfiltrate */
    return 0;
}

Userspace daha sonra leak edilen byte'ları almak için out_map'i okur. Man page, kernel ve user read'lerini ayıran açık bpf_probe_read_kernel() / bpf_probe_read_user() varyantlarını kullanmayı tavsiye ediyor.

Warning

Bu helper'ı sadece tracing BPF program'ları alır. BPF design FAQ, networking program'larının "cannot read arbitrary memory, since they don't have access to these helpers" olduğunu belirtiyor — arbitrary-read gücü tracing program tiplerine özgü.

Detection

Tracing BPF program'larının yüklenmesi audit edilebilir (BPF program load event'leri, attach edilmiş kprobe'lar); kernel memory okuyup dışarı aktaran beklenmedik kprobe/tracepoint program'ları bir sinyaldir.

Mitigation

Kernel BPF design FAQ'a göre, "Tracing BPF programs are root only" — helper privileged context'lerle sınırlandırılmıştır. BPF/tracing capability'lerini kısıtlayın (CAP_BPF, CAP_PERFMON, CAP_SYS_ADMIN), kernel.unprivileged_bpf_disabled=1 ayarlayın ve kernel.perf_event_paranoid'i öyle sınırlayın ki unprivileged kullanıcılar tracing program'larını attach edemesin.

References