🇰🇷 한글 설명
리눅스 커널의 net/sched 구성 요소에서 qdisc_dequeue_internal 함수가 gso_skb를 처리할 때 백로그(backlog) 통계를 정확하게 감소시키지 못하는 취약점이 발견되었습니다. 이로 인해 특정 qdisc(hhf, fq, fq_codel, fq_pie) 사용 시 백로그 값이 실제보다 높게 유지되어, 이후 TBF 부모 qdisc에서 백로그 언더플로우(underflow)가 발생할 수 있습니다.
💡 쉬운 설명
네트워크 데이터가 쌓인 양을 계산하는 과정에서 오류가 발생하여, 실제로는 데이터가 없는데도 데이터가 가득 차 있는 것으로 잘못 인식될 수 있습니다. 이로 인해 시스템의 네트워크 관리 기능이 오작동하거나 계산 오류가 발생할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
net/sched: Fix backlog accounting in qdisc_dequeue_internal
This issue applies for the following qdiscs: hhf, fq, fq_codel, and
fq_pie, and occurs in their change handlers when adjusting to the new
limit. The problem is the following in the values passed to the
subsequent qdisc_tree_reduce_backlog call given a tbf parent:
When the tbf parent runs out of tokens, skbs of these qdiscs will
be placed in gso_skb. Their peek handlers are qdisc_peek_dequeued,
which accounts for both qlen and backlog. However, in the case of
qdisc_dequeue_internal, ONLY qlen is accounted for when pulling
from gso_skb. This means that these qdiscs are missing a
qdisc_qstats_backlog_dec when dropping packets to satisfy the
new limit in their change handlers.
One can observe this issue with the following (with tc patched to
support a limit of 0):
export TARGET=fq
tc qdisc del dev lo root
tc qdisc add dev lo root handle 1: tbf rate 8bit burst 100b latency 1ms
tc qdisc replace dev lo handle 3: parent 1:1 $TARGET limit 1000
echo ''; echo 'add child'; tc -s -d qdisc show dev lo
ping -I lo -f -c2 -s32 -W0.001 127.0.0.1 2>&1 >/dev/null
echo ''; echo 'after ping'; tc -s -d qdisc show dev lo
tc qdisc change dev lo handle 3: parent 1:1 $TARGET limit 0
echo ''; echo 'after limit drop'; tc -s -d qdisc show dev lo
tc qdisc replace dev lo handle 2: parent 1:1 sfq
echo ''; echo 'post graft'; tc -s -d qdisc show dev lo
The second to last show command shows 0 packets but a positive
number (74) of backlog bytes. The problem becomes clearer in the
last show command, where qdisc_purge_queue triggers
qdisc_tree_reduce_backlog with the positive backlog and causes an
underflow in the tbf parent's backlog (4096 Mb instead of 0).
To fix this issue, the codepath for all clients of qdisc_dequeue_internal
has been simplified: codel, pie, hhf, fq, fq_pie, and fq_codel.
qdisc_dequeue_internal handles the backlog adjustments for all cases that
do not directly use the dequeue handler.
The old fq_codel_change limit adjustment loop accumulated the arguments to
the subsequent qdisc_tree_reduce_backlog call through the cstats field.
However, this is confusing and error prone as fq_codel_dequeue could also
potentially mutate this field (which qdisc_dequeue_internal calls in the
non gso_skb case), so we have unified the code here with other qdiscs.
📍 영향받는 시스템
Linux Kernel (hhf, fq, fq_codel, fq_pie qdisc를 사용하는 시스템)
⚔️ 공격 벡터
로컬 네트워크 설정 변경(tc 명령 등)을 통해 특정 qdisc의 한계치를 조정하여 백로그 통계 오류를 유도함
🛡️ 대응 방법
리눅스 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 qdisc_dequeue_internal의 백로그 조정 로직을 수정해야 함
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전 이후인지 확인하십시오.