Skip to content

eBPF verifier register-limit tracking bug (CVE-2023-2163)

backtrack_insn(), register-vs-register conditional'larda source register'ı precise işaretlemeyi atladı; bu yüzden verifier eşdeğer sandığı güvensiz bir path'i prune etti — arbitrary kernel R/W (Google Buzzer/fuzzing bulgusu).

Mechanism

Note

jmp/jmp32 instruction class'ı için backtrack_insn() (kernel/bpf/verifier.c içindeki precision-tracking backtracker'ı) yalnızca call/exit'i ele alıyordu; diğer tüm conditional'larda precision mask'leri olduğu gibi kalıyordu. Yani r6 r9'a bağlı olsa bile sadece r6 precise işaretlendiyse, r9 hiçbir zaman precise işaretlenmiyordu. Bu taint'in eksik olması verifier'ın iki state'i eşdeğer sayıp prune etmesine yol açar — runtime'da aslında alınan güvensiz path'i atlar.

Commit'in alıntıladığı örnek state'ler: eski R6_rwD=Pscalar() R9_rwD=0 vs yeni R6_w=scalar(umax=...) R9_w=-2147483648. r9 farklıdır (0 vs 0x80000000) ama precise flag'i olmadığından sayılmaz, dolayısıyla güvenli kabul edilen pruning yanlıştır. Runtime'da r6=0x400, r9=0x80000000 olur ve bir OOB map access üretir.

Walkthrough

PoC'nin sonu, verifier'ın in-bounds sandığı bir OOB read+write yapar:

21: (77) r6 >>= 10
22: (27) r6 *= 8192
23: (bf) r1 = r0
24: (0f) r0 += r6          ; verifier thinks r6==0; runtime large -> OOB
25: (79) r3 = *(u64 *)(r0 +0)   ; OOB read
26: (7b) *(u64 *)(r1 +0) = r3   ; write back into map_value
27: (95) exit

NVD'ye göre bu, "güvensiz code path'lerin yanlışlıkla safe işaretlenmesi, bunun sonucunda kernel memory'sinde arbitrary read/write, lateral privilege escalation ve container escape" ile sonuçlanır. CAP_BPF veya CAP_SYS_ADMIN gerektirir.

Warning

Fix commit 71b547f56124 ("Fix incorrect verifier pruning due to missing register precision taints", Daniel Borkmann), Fixes: b5dc0163d8fd. 5.4'ten 6.2 serisine kadarki sürümleri etkiledi; 6.3 mainline (fix'in landed olduğu release) etkilenmez. Stable backport'lar: 5.4.242 / 5.10.179 / 5.15.109 / 6.1.26 / 6.2.13 (6.3'te fix mainline'da bulunduğundan ayrı bir backport gerekmez). Fix, hem sreg'i hem dreg'i reg_mask'e OR'layan bir BPF_SRC == BPF_X branch'i ekler. (Not: bu CVE find_equal_scalars/sync_linked_regs içinde değildir.)

Mitigation

sysctl kernel.unprivileged_bpf_disabled=1 ve unprivileged context'lerden CAP_BPF'i düşürmek; fix precision propagation'ı geri getirir, böylece güvensiz path artık prune edilmez ve program reddedilir ("math between map_value pointer and register with unbounded min value is not allowed").

References