[하루한줄] CVE-2021-31440: Linux Kernel eBPF verifier, incorrect bound check

URL

CVE-2021-31440: AN INCORRECT BOUNDS CALCULATION IN THE LINUX KERNEL EBPF VERIFIER

Target

Linux kernel 5.7 ~ Linux kernel 5.11.15

Explain

eBPF는 런타임 중 안전하게 커널 코드를 삽입하기 위해 Verifier와 BPF instruction을 사용합니다. Verifier는 레지스터의 값의 변화와 그 값들의 허용 범위(이하 range)등을 추적해 memory load와 store의 out-of-bound 여부를 검사합니다. CVE-2021-31440을 악용하면 out-of-bound 검사를 무력화하고 로컬 권한 상승을 노릴 수 있습니다.

...
    if (__reg64_bound_u32(reg->umin_value))     
        reg->u32_min_value = (u32)reg->umin_value; 
    if (__reg64_bound_u32(reg->umax_value))     
        reg->u32_max_value = (u32)reg->umax_value;
...

위는 취약한 코드 부분의 일부입니다. 기존 eBPF 취약점들과 마찬가지로 CVE-2021-31440 또한 64 bit range의 하위 32 비트로부터 32 bit range를 도출하는 과정에서 버그가 발생합니다. umin_value가 1, umax_value 가 1<<32이라 할 때 u32_min_value는 1, u32_max_value는 0으로 설정되고 실제 runtime range와 다른 값을 Verifier에게 전달하게 됩니다.

Verifier는 잘못된 레지스터 허용범위를 갖게 되고 이를 통해 해커는 out-of-bound read/write access가 가능해 로컬 권한 상승을 할 수 있습니다.