🇰🇷 한글 설명
Linux 커널의 AF_XDP 멀티 버퍼 Tx 처리 과정에서 xsk_drop_skb() 함수 호출 시 버퍼 누수가 발생하는 취약점입니다. 패킷 크기 초과나 소켓 종료 시 CQ(Completion Queue) 예약은 취소되지만 버퍼 주소가 제대로 반환되지 않아 메모리 관리에 문제가 생깁니다. 이를 해결하기 위해 xsk_destruct_skb()를 호출하여 버퍼 주소를 CQ에 제출하도록 수정되었습니다.
💡 쉬운 설명
데이터를 주고받는 통로에서 처리 중 오류가 발생했을 때, 사용하던 메모리 공간을 시스템에 다시 돌려주지 않고 잃어버리는 버그입니다. 이 문제가 지속되면 시스템의 메모리가 조금씩 줄어들어 결국 성능 저하나 문제가 생길 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
xsk: fix buffer leak in xsk_drop_skb() for AF_XDP multi-buffer Tx
This patch is inspired by the check[1] from sashiko. It says when
overflow happens, the address of cq to be published is invalid.
Actually the severer thing is the whole process of publishing the
address of cq in this particular case is not right: it should truely
publish the address and advance the cached_prod in cq as long as it
reads descriptors from txq.
The following is the full analysis.
xsk_drop_skb() is called in three places, which all discard a partially
built multi-buffer skb:
1) xsk_build_skb() -EOVERFLOW error path: packet exceeds MAX_SKB_FRAGS
2) __xsk_generic_xmit() post-loop cleanup: an invalid descriptor in
the TX ring prevents the partial packet from completing
3) xsk_release(): socket close while xs->skb holds an incomplete packet
In all three cases, the TX descriptors for the already-processed frags
have been consumed from the TX ring (xskq_cons_release), and CQ slots
have been reserved. However, xsk_drop_skb() calls xsk_consume_skb()
which cancels the CQ reservations via xsk_cq_cancel_locked(). Since
the buffer addresses never appear in the completion queue, userspace
permanently loses track of these buffers.
Fix this by letting consume_skb() trigger the existing xsk_destruct_skb
destructor, which already submits buffer addresses to the CQ via
xsk_cq_submit_addr_locked().
Note that cancelling the descriptors back to the TX ring (via
xskq_cons_cancel_n) is not a appropriate option because an oversized
packet that always exceeds MAX_SKB_FRAGS would be retried indefinitely,
which is an obviously deadlock bug in the TX path.
Also move the desc->addr assignment in xsk_build_skb() above the
overflow check so that the current descriptor's address is recorded
before a potential -EOVERFLOW jump to free_err, consistent with the
zerocopy path in xsk_build_skb_zerocopy().
[1]: https://lore.kernel.org/all/
[email protected]/
📍 영향받는 시스템
AF_XDP 멀티 버퍼 Tx 기능을 사용하는 Linux Kernel (패치 적용 전 버전)
⚔️ 공격 벡터
직접적인 공격보다는 대량의 비정상적인 패킷(MAX_SKB_FRAGS 초과)을 전송하여 점진적인 메모리 누수를 유도하는 방식
🛡️ 대응 방법
해당 버그가 수정된 최신 Linux 커널 버전으로 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 패치가 적용된 최신 버전인지 확인
💻 영향받는 소프트웨어
NVIDIA Cloud Gaming Guest Driver for Linux