🇰🇷 한글 설명
리눅스 커널의 BPF 서브시스템 내 bpf_prog_test_run_xdp() 함수에서 초기화되지 않은 포인터로 인한 NULL 포인터 역참조 취약점이 발견되었습니다. BPF 테일콜(tailcall) 사용 시 expected_attach_type에 따른 제약 사항을 강제하지 않아 발생하며, 이를 통해 잘못된 메모리 접근이 가능해집니다.
💡 쉬운 설명
프로그램이 특정 규칙을 지키지 않고 다른 기능을 호출할 때, 컴퓨터가 잘못된 메모리 주소를 참조하여 시스템이 멈추거나 오류가 발생할 수 있는 문제입니다. 보안 규칙을 검사하는 과정에서 허점이 있어 발생한 현상입니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
bpf: Enforce expected_attach_type for tailcall compatibility
Yinhao et al. recently reported:
Our fuzzer tool discovered an uninitialized pointer issue in the
bpf_prog_test_run_xdp() function within the Linux kernel's BPF subsystem.
This leads to a NULL pointer dereference when a BPF program attempts to
deference the txq member of struct xdp_buff object.
The test initializes two programs of BPF_PROG_TYPE_XDP: progA acts as the
entry point for bpf_prog_test_run_xdp() and its expected_attach_type can
neither be of be BPF_XDP_DEVMAP nor BPF_XDP_CPUMAP. progA calls into a slot
of a tailcall map it owns. progB's expected_attach_type must be BPF_XDP_DEVMAP
to pass xdp_is_valid_access() validation. The program returns struct xdp_md's
egress_ifindex, and the latter is only allowed to be accessed under mentioned
expected_attach_type. progB is then inserted into the tailcall which progA
calls.
The underlying issue goes beyond XDP though. Another example are programs
of type BPF_PROG_TYPE_CGROUP_SOCK_ADDR. sock_addr_is_valid_access() as well
as sock_addr_func_proto() have different logic depending on the programs'
expected_attach_type. Similarly, a program attached to BPF_CGROUP_INET4_GETPEERNAME
should not be allowed doing a tailcall into a program which calls bpf_bind()
out of BPF which is only enabled for BPF_CGROUP_INET4_CONNECT.
In short, specifying expected_attach_type allows to open up additional
functionality or restrictions beyond what the basic bpf_prog_type enables.
The use of tailcalls must not violate these constraints. Fix it by enforcing
expected_attach_type in __bpf_prog_map_compatible().
Note that we only enforce this for tailcall maps, but not for BPF devmaps or
cpumaps: There, the programs are invoked through dev_map_bpf_prog_run*() and
cpu_map_bpf_prog_run*() which set up a new environment / context and therefore
these situations are not prone to this issue.
📍 영향받는 시스템
Linux Kernel (BPF subsystem 사용 환경)
⚔️ 공격 벡터
특정 조건의 BPF 프로그램을 작성하여 테일콜을 통해 보안 제약 사항을 우회하고 NULL 포인터를 유도하는 방식
🛡️ 대응 방법
리눅스 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 __bpf_prog_map_compatible()의 검증 로직을 적용해야 합니다.
🔧 검증 코드
출력된 커널 버전을 확인하여 해당 취약점이 해결된 최신 패치 버전인지 확인합니다.