🇰🇷 한글 설명
Linux 커널의 xprtrdma 구성 요소에서 RDMA_CM_EVENT_ESTABLISHED 이벤트가 발생하기 전에 ADDR_CHANGE 이벤트가 도착할 경우 kref 참조 횟수 불균형이 발생합니다. 이로 인해 참조 횟수가 언더플로우되어 연결 해제 과정에서 이미 해제된 메모리(ep)에 접근하는 Use-After-Free 취약점이 발생할 수 있습니다.
💡 쉬운 설명
네트워크 연결이 완전히 이루어지기 전에 주소 변경 신호가 들어오면, 컴퓨터가 이미 삭제된 메모리 정보를 다시 사용하려고 시도하는 오류입니다. 이 과정에서 시스템이 충돌하거나 보안 문제가 생길 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
xprtrdma: Fix ep kref imbalance on ADDR_CHANGE
rpcrdma_cm_event_handler() falls through to the disconnected: label
on RDMA_CM_EVENT_ADDR_CHANGE and calls rpcrdma_ep_put() with no
matching get when the event arrives before RDMA_CM_EVENT_ESTABLISHED.
The kref then underflows during connect teardown and
rpcrdma_xprt_disconnect() operates on a freed ep.
Reference counts across a normal connection lifecycle:
rpcrdma_ep_create() kref_init ->1
rpcrdma_xprt_connect() ep_get ->2 (before post_recvs)
RDMA_CM_EVENT_ESTABLISHED ep_get ->3
RDMA_CM_EVENT_DISCONNECTED ep_put ->2
rpcrdma_xprt_drain() ep_put ->1
rpcrdma_xprt_disconnect() tail ep_put ->0 (ep_destroy)
The connect-time get in rpcrdma_xprt_connect(), taken just before
rpcrdma_post_recvs() "while there are outstanding Receives," is
balanced by rpcrdma_xprt_drain. ADDR_CHANGE before ESTABLISHED has
no get to consume, so its put drops the count to 1 and the drain
put then frees the ep while rpcrdma_xprt_disconnect() still holds a
pointer to it.
Fix by dispatching on the prior re_connect_status via xchg(): for
prev == 0 (pre-ESTABLISHED) wake the connect waiter and return with
no put; for prev == 1 call rpcrdma_force_disconnect() and return.
The case-1 arm relies on the subsequent RDMA_CM_EVENT_DISCONNECTED
event -- reliably delivered when rdma_disconnect() is called on a
still-connected cm_id -- to balance the ESTABLISHED get;
rpcrdma_xprt_drain() continues to balance only that connect-time
get. Any other prior value means teardown is already in flight.
📍 영향받는 시스템
Linux kernel (xprtrdma module 포함 버전)
⚔️ 공격 벡터
RDMA 연결 수립 과정 중 특정 타이밍에 주소 변경(ADDR_CHANGE) 이벤트를 유도하여 메모리 오류 유발
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전 이후인지 확인