🇰🇷 한글 설명
Linux 커널의 Intel ICE 드라이버에서 Tx 도어벨 갱신에 writel_relaxed()를 사용하여 DQL 큐 accounting 업데이트와 NIC 전송 시작 사이의 순서가 보장되지 않았습니다. 이로 인해 arm64 환경에서 dql_completed()의 BUG_ON이 발생할 수 있으며, writel()로 복원하여 수정되었습니다.
💡 쉬운 설명
네트워크 카드가 데이터 전송 기록을 정리하기 전에 전송을 끝내버려서 커널이 잘못된 상태로 판단하고 충돌하는 문제입니다. 쓰기 순서를 보장하도록 수정하여 해결되었습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
ice: Restore Ordered MMIO Writes for Tx Doorbells
The DQL accounting state which tracks the number of bytes queued for the
NIC to transmit, namely dql->num_queued, is updated by the ICE driver
when it invokes __netdev_tx_sent_queue(). Subsequently the driver
updates the hardware queue tail allowing the NIC to begin processing the
work queue. The queue accounting update should be ordered before the NIC
begins transmitting descriptors.
The transmit path currently updates the hardware doorbell using
writel_relaxed(), which (on arm64) does not provide the same ordering
guarantees between writes to normal memory and writes to MMIO registers
that writel() does. This introduces a potential race where the NIC
begins transmitting descriptors before the dql->num_queued update is
globally visible. If the NIC finishes before the update is observed by
dql_completed(), it detects an invalid state where more bytes have been
completed than have been queued. When this happens the following BUG_ON
is triggered.
BUG_ON(count > num_queued - dql->num_completed);
This has been observed and manifests as the following crash (note that
the trace has been trimmed) in an environment with sustained network
load that uses an Intel Corporation Ethernet Controller E810-XXV for SFP
(rev 02) on an arm64 machine. Replacing writel_relaxed() with writel()
in a test kernel eliminated the crash in the user's workload, which
previously reproduced the issue reliably.
kernel BUG at lib/dynamic_queue_limits.c:99
Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
pc : dql_completed+0x268/0x2a0
lr : ice_clean_tx_irq+0x1d4/0x620 [ice]
Call trace:
dql_completed+0x268/0x2a0 (P)
ice_napi_poll+0x94/0x520 [ice]
__napi_poll+0x48/0x3f0
net_rx_action+0x194/0x420
This restores the behaviour prior to commit ccde82e90946 ("ice: add E830
Earliest TxTime First Offload support"), which changed the notification
mechanism from writel() to writel_relaxed().
📍 영향받는 시스템
Intel E810 이더넷 컨트롤러(ice 드라이버)를 사용하는 arm64 기반 Linux 커널 시스템 (ccde82e90946 커밋 이후 버전)
⚔️ 공격 벡터
직접적인 원격 공격 벡터는 명시되지 않으며, 지속적인 네트워크 부하 상황에서 발생하는 커널 충돌(DoS) 위험
🛡️ 대응 방법
Linux 커널을 해당 수정이 포함된 최신 버전으로 업데이트하여 writel_relaxed()가 writel()로 복원된 드라이버를 사용
🔧 검증 코드
커널 버전이 수정 패치가 포함된 최신 배포판 커널인지 확인하고, ice 모듈 정보가 출력되면 해당 드라이버가 로드 가능한 상태이며 벤더 업데이트 여부를 추가로 확인해야 합니다.
uname -r && modinfo ice 2>/dev/null | grep -E '^(version|filename)'