🇰🇷 한글 설명
Linux 커널의 네트워크 스택에서 SO_RESERVE_MEM 소켓 옵션이 TCP뿐만 아니라 UDP 소켓에서도 허용되어 발생하는 취약점입니다. 이로 인해 UDP 패킷 수신 과정에서 메모리 계정(accounting) 오류 및 데이터 손상이 발생할 수 있으며, 설정 값의 상한선이 없어 정수 오버플로를 통한 메모리 손상 가능성이 존재합니다.
💡 쉬운 설명
네트워크 통신을 조절하는 설정값이 잘못 적용되어 컴퓨터의 메모리 계산 방식에 오류를 일으킬 수 있는 문제입니다. 이 오류를 이용하면 시스템의 메모리 관리 기능이 망가질 위험이 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
net: restrict SO_RESERVE_MEM to TCP sockets and cap max value
Commit 2bb2f5fb21b0 ("net: add new socket option SO_RESERVE_MEM") and
commit d00c8ee31729 ("net: fix possible NULL deref in sock_reserve_memory")
only checked sk_has_account(sk), which is true for both TCP and UDP
sockets.
However, SO_RESERVE_MEM and sk_unused_reserved_mem() are currently only
supported by TCP:
- On UDP sockets, sk->sk_forward_alloc is protected by
sk->sk_receive_queue.lock, whereas sock_reserve_memory() and
sock_release_reserved_memory() only acquire lock_sock(sk). Concurrent
UDP packet reception/release and setsockopt(SO_RESERVE_MEM) corrupt
sk_forward_alloc and memcg accounting.
- udp_rmem_release() reclaims excess sk_forward_alloc without
accounting for sk_unused_reserved_mem(sk).
Restrict sock_reserve_memory() to TCP sockets (sk_is_tcp(sk)) for now.
Supporting SO_RESERVE_MEM for UDP (acquiring sk_receive_queue.lock and
honoring sk_unused_reserved_mem() in udp_rmem_release()) can be done in
a future net-next series if needed.
In addition, reject val > SZ_1G with -EINVAL in
sk_setsockopt(SO_RESERVE_MEM). Without an upper bound, values near
INT_MAX cause sk_mem_pages(delta) and (pages << PAGE_SHIFT) to overflow
32-bit signed int, corrupting sk->sk_forward_alloc and
sk->sk_reserved_mem. Using a page-aligned cap (SZ_1G) ensures that the
page-rounded sk->sk_reserved_mem reported by getsockopt(SO_RESERVE_MEM)
can always be passed back to setsockopt(SO_RESERVE_MEM).
📍 영향받는 시스템
SO_RESERVE_MEM 옵션이 포함된 커널 패치가 적용되지 않은 Linux 커널 버전
⚔️ 공격 벡터
UDP 소켓에 SO_RESERVE_MEM 옵션을 설정하거나 매우 큰 값을 입력하여 메모리 계정 오류 및 정수 오버플로 유도
🛡️ 대응 방법
SO_RESERVE_MEM 옵션을 TCP 소켓으로 제한하고 설정 값의 최대치를 1GB로 제한하는 커널 패치 적용
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 최신 패치 버전인지 확인