🇰🇷 한글 설명
Linux 커널의 BPF sock_ops 프로그램에서 동일한 레지스터를 목적지와 소스로 사용할 때 발생하는 Out-of-Bounds 읽기 및 포인터 유출 취약점입니다. 특정 조건에서 목적지 레지스터가 0으로 초기화되지 않아 잘못된 소켓 포인터를 사용하거나 커널 포인터가 유출될 수 있습니다.
💡 쉬운 설명
리눅스 시스템의 특정 기능을 사용하는 프로그램이 메모리의 잘못된 위치를 읽거나 중요한 내부 주소를 외부로 흘릴 수 있는 보안 약점입니다. 이로 인해 시스템의 보안 경계가 무너질 위험이 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
bpf: Fix same-register dst/src OOB read and pointer leak in sock_ops
When a BPF sock_ops program accesses ctx fields with dst_reg == src_reg,
the SOCK_OPS_GET_SK() and SOCK_OPS_GET_FIELD() macros fail to zero the
destination register in the !fullsock / !locked_tcp_sock path.
Both macros borrow a temporary register to check is_fullsock /
is_locked_tcp_sock when dst_reg == src_reg, because dst_reg holds the
ctx pointer. When the check is false (e.g., TCP_NEW_SYN_RECV state with
a request_sock), dst_reg should be zeroed but is not, leaving the stale
ctx pointer:
- SOCK_OPS_GET_SK: dst_reg retains the ctx pointer, passes NULL checks
as PTR_TO_SOCKET_OR_NULL, and can be used as a bogus socket pointer,
leading to stack-out-of-bounds access in helpers like
bpf_skc_to_tcp6_sock().
- SOCK_OPS_GET_FIELD: dst_reg retains the ctx pointer which the
verifier believes is a SCALAR_VALUE, leaking a kernel pointer.
Fix both macros by:
- Changing JMP_A(1) to JMP_A(2) in the fullsock path to skip the
added instruction.
- Adding BPF_MOV64_IMM(si->dst_reg, 0) after the temp register
restore in the !fullsock path, placed after the restore because
dst_reg == src_reg means we need src_reg intact to read ctx->temp.
📍 영향받는 시스템
Linux Kernel (BPF sock_ops 기능을 사용하는 버전)
⚔️ 공격 벡터
조작된 BPF sock_ops 프로그램을 실행하여 커널 메모리 읽기 및 포인터 유출 유도
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전 이후인지 확인