🇰🇷 한글 설명
Linux 커널의 Atlantic 네트워크 드라이버에서 인터페이스 종료 시 TX 버퍼가 제대로 해제되지 않는 메모리 누수 취약점이 발견되었습니다. 특히 XDP_TX 부하가 있는 상황에서 인터페이스를 내리거나 XDP를 분리할 때, 참조되지 않는 프레임이 남아 page_pool이 해제되지 않고 시스템 리소스를 계속 점유하게 됩니다.
💡 쉬운 설명
네트워크 카드를 끄거나 설정을 바꿀 때, 사용하던 메모리를 깨끗이 치우지 못하고 버리는 문제가 있습니다. 이 문제가 반복되면 컴퓨터의 메모리가 조금씩 계속 줄어들어 결국 시스템 성능이 떨어지거나 문제가 생길 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
net: atlantic: free stranded TX buffers on ring deinit
aq_vec_deinit() drains the TX rings with a single aq_ring_tx_clean()
call, which frees at most AQ_CFG_TX_CLEAN_BUDGET (256) descriptors and
stops at hw_head, which no longer moves once aq_vec_stop() has stopped
the hardware and NAPI. Completed descriptors beyond the budget and
everything still posted in [hw_head, sw_tail) keep their skb or
xdp_frame when the interface goes down: aq_vec_ring_free() then frees
the buffer ring and the references are lost for good.
Today this is a silent memory leak on every interface down under
TX/XDP_TX load. With the conversion of the RX path to page_pool posted
for net-next it becomes much more visible: XDP_TX frames carry fragment
references on the RX ring's page_pool, so a single stranded frame keeps
the pool's inflight count above zero forever. page_pool_destroy() then
never completes, the pool is leaked together with its pages, and
"page_pool_release_retry() stalled pool shutdown" is warned every 60
seconds from that point on, on every ifdown, XDP detach or ring resize
under XDP_TX load.
Bring back aq_ring_tx_deinit() as it was before the removal and use it
for teardown again, with one extension: TX rings can hold xdp_frames
nowadays, so release those too. They are returned with
xdp_return_frame() since this runs in process context.
📍 영향받는 시스템
Linux kernel (Atlantic network driver 사용 환경)
⚔️ 공격 벡터
직접적인 공격보다는 지속적인 네트워크 인터페이스 조작(ifdown, XDP detach 등)을 통한 리소스 고갈 유도
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 aq_ring_tx_deinit() 로직이 포함된 수정본을 적용해야 합니다.
🔧 검증 코드
명령어 실행 결과에 'stalled pool shutdown' 경고 메시지가 출력된다면 해당 취약점이 발생하여 메모리 누수가 진행 중임을 의미합니다.
dmesg | grep -i 'page_pool_release_retry() stalled pool shutdown'