🇰🇷 한글 설명
Linux 커널의 net/sched 구성 요소에서 tc 분류기 필터 할당 시 memcg(메모리 제어 그룹) 계정이 적용되지 않는 취약점이 발견되었습니다. 이로 인해 권한이 없는 사용자가 메모리 제한을 우회하여 커널 메모리를 무제한으로 점유할 수 있으며, 특정 경로에서는 dangling pointer를 유발하는 오류도 포함되어 있습니다.
💡 쉬운 설명
사용자가 정해진 메모리 사용량을 넘지 못하도록 제한을 걸어두어도, 특정 네트워크 설정 기능을 이용해 이 제한을 무시하고 시스템 메모리를 계속 써버릴 수 있는 문제입니다. 결과적으로 시스템의 메모리가 고갈되어 컴퓨터가 느려지거나 멈출 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
net/sched: account classifier filter allocations to memcg
Allocations in the tc classifier *_change() paths (filter objects,
per-CPU counters, and per-filter aux data) use plain GFP_KERNEL without
__GFP_ACCOUNT, allowing unprivileged users to pin kernel memory outside
memcg charging. The shared tcf_exts_init_ex() action array allocation in
cls_api.c was also uncharged; this patch closes it along with the
per-classifier filter-object/percpu/aux allocations that remain
unaccounted.
Add GFP_KERNEL_ACCOUNT to:
- the shared tcf_exts_init_ex() action array (cls_api.c), common to every
filter of every classifier (32 pointers, 256 bytes);
- the filter-object, per-CPU-counter, and per-filter aux allocations in
cls_basic, cls_bpf, cls_cgroup, cls_flow, cls_flower, cls_fw,
cls_matchall, cls_route and cls_u32;
- the u32_init_knode() replace-path knode allocation (cls_u32.c), which
allocates the same struct tc_u_knode + sel.keys on every replace of an
existing knode and was missed by the create-path-only conversion.
Also fix the cls_basic error path: basic_change() inserts fnew into the
IDR before allocating the per-CPU counter. If alloc_percpu() fails the
errout path kfree'd fnew without idr_remove, leaving a dangling pointer
in the IDR. With GFP_KERNEL_ACCOUNT the percpu alloc becomes failable
on demand (memcg at memory.max), making the dead path attacker-reachable
and burning the handle permanently. Add the idr_remove on the percpu
failure path, matching the basic_set_parms failure-path pattern.
Note:
[email protected] provided a poc for basic_cls, but it was easy to
extend to the other classifiers.
Conditions to recreate the bug:
- CONFIG_NET_SCHED, CONFIG_NET_CLS_* (the classifier being used),
CONFIG_NET_CLS_ACT, CONFIG_MEMCG, CONFIG_USER_NS, CONFIG_NET_NS.
- Unprivileged user in a fresh user+network namespace (unshare -Urn),
or root with CAP_NET_ADMIN.
- Create a large number of tc filters (e.g. tc filter add dev lo
ingress ... <classifier> ...) while watching a memcg-limited cgroup:
system slab grows far faster than memory.current, pinning kernel
memory outside memcg charging.
📍 영향받는 시스템
CONFIG_NET_SCHED, CONFIG_MEMCG, CONFIG_USER_NS 등이 활성화된 Linux 커널
⚔️ 공격 벡터
비특권 사용자가 새로운 사용자/네트워크 네임스페이스를 생성한 후, tc 필터를 대량으로 생성하여 memcg 제한을 우회하는 방식
🛡️ 대응 방법
커널 패치를 통해 tc 분류기 할당 시 GFP_KERNEL_ACCOUNT 플래그를 적용하고, 오류 발생 시 IDR 제거 로직을 수정해야 함
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 패치된 최신 보안 업데이트 버전인지 확인하십시오.