Skip to content

eBPF verifier register-limit vulnerability (CVE-2024-41003)

Bir register-vs-const karşılaştırmasının iki branch'i aynı geçici "fake" register'ı paylaşıyordu; bu yüzden bir branch'in bounds'unu güncellemek diğerini bozuyordu — geçersiz bir min>max state'i ve bir arbitrary kernel R/W primitive'i üretiyordu.

Mechanism

Note

kernel/bpf/verifier.c içindeki reg_set_min_max() bir constant'a karşı karşılaştırmayı ele alırken geçici bir fake register kurar. False-branch ve true-branch register-2 pointer'ları (false_reg2, true_reg2) aynı fake register'ı gösteriyordu; bu yüzden bir branch'in bounds'unu güncellemek diğerininkini bozuyordu. Sonuç min > max olan geçersiz bir register state'idir (bir "REG INVARIANTS VIOLATION", örn. verifier R6_w=0 ile biterken runtime değeri 1'dir). CAP_BPF ile bu, bir arbitrary kernel memory read/write primitive'i ve local privilege escalation verir.

Bug, Google'ın Buzzer BPF fuzzer'ı ile bulundu (2024-06-07'de raporlandı, 2024-06-13'te düzeltildi). CVSS 7.8, CWE-787 (out-of-bounds write).

Walkthrough

Fix her branch'e fake register'ın kendi kopyasını verir, onu stack'ten verifier env'ine taşır:

/* include/linux/bpf_verifier.h: struct bpf_reg_state fake_reg[2]; */
memcpy(&env->fake_reg[1], &env->fake_reg[0], sizeof(env->fake_reg[0]));
/* pass &env->fake_reg[0] and &env->fake_reg[1] instead of one shared pointer */

Bir program, iki branch'ini verifier'ın çapraz-bozduğu bir register-vs-const karşılaştırması hazırlar; track edilen bounds'u runtime'la uyuşmayan geçersiz bir scalar ile biter — bu OOB primitive'i (daha geniş verifier-abuse pattern'inde olduğu gibi) kernel memory'sini read/write etmek ve privilege escalation için kullanılır.

Warning

Fix commit 41e8ab428a99 ("bpf: Fix reg_set_min_max corruption of fake_reg", Daniel Borkmann), Fixes: 67420501e868 ("generalize reg_set_min_max() to handle non-const register comparisons"). Linux 6.8'den 6.9.6'ya kadarki sürümleri etkiledi; 6.9.7'de düzeltildi.

Mitigation

sysctl kernel.unprivileged_bpf_disabled=1 ve CAP_BPF'i düşürmek; fix iki branch'in fake register'larını izole eder, böylece hiçbiri diğerini bozmaz.

References