🇰🇷 한글 설명
리눅스 커널의 Netlink 구현에서 메모리 재할당 시 발생하는 Use-After-Free 취약점입니다. krealloc() 사용 시 기존 비트맵이 즉시 해제되어, 락을 사용하지 않는 읽기 작업(sk_diag_dump_groups, netlink_native_seq_show)이 해제된 메모리에 접근하거나 잘못된 크기의 데이터를 읽을 수 있습니다.
💡 쉬운 설명
컴퓨터가 데이터를 저장하는 공간을 늘리는 과정에서, 기존 공간을 너무 빨리 지워버려 다른 프로그램이 이미 사라진 데이터를 읽으려다 오류가 발생하는 문제입니다. 이로 인해 시스템이 불안정해지거나 잘못된 정보를 읽을 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
netlink: do not free nlk->groups while lockless readers can use it
netlink_realloc_groups() uses krealloc() under netlink_table_grab().
Whenever NLGRPSZ(groups) lands in a different kmalloc bucket, the old
bitmap is freed immediately.
Two readers of nlk->groups / nlk->ngroups do not hold the netlink
table lock:
1) sk_diag_dump_groups(). Hashed (bound) sockets are dumped from the
rhashtable walk in __netlink_diag_dump(), which only holds RCU.
Only the mc_list part of the dump takes nl_table_lock.
2) netlink_native_seq_show() (/proc/net/netlink), whose walk has been
lockless since commit 21e4902aea80 ("netlink: Lockless lookup with
RCU grace period in socket release").
Both can read a freed buffer, and sk_diag_dump_groups() can also read
past the end of the old (smaller) buffer if it happens to load the old
@groups pointer together with the new @ngroups value, copying the
result into a NETLINK_DIAG_GROUPS attribute.
This is the same class of bug that commit f773608026ee ("netlink:
access nlk groups safely in netlink bind and getname") fixed for bind()
and getname(); these two readers were missed. Simply grabbing the table
lock in sk_diag_dump_groups() is not an option, because it is also
called with nl_table_lock already held from the mc_list section of the
dump.
Make the lockless readers safe instead:
- Allocate a new bitmap and free the old one after an RCU grace period,
instead of relying on the implicit kfree() done by krealloc().
- Publish @groups before @ngroups, both with release semantics, and have
the lockless readers load @ngroups first. A reader can then never pair
the new (bigger) size with the old (smaller) buffer, and a reader
picking up the new pointer while still seeing the old size is
guaranteed to see the initialized bitmap.
netlink_realloc_groups() is called from process context (bind() and
setsockopt()), so kfree_rcu_mightsleep() can be used, once the table
has been released.
📍 영향받는 시스템
Linux Kernel (Netlink 관련 모듈을 사용하는 모든 시스템)
⚔️ 공격 벡터
로컬 공격자가 Netlink 소켓 조작 및 특정 진단 도구(diag dump)를 호출하여 메모리 오류 유도
🛡️ 대응 방법
커널 패치를 적용하여 RCU grace period를 통한 안전한 메모리 해제 및 원자적 업데이트 로직 적용
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 최신 패치 버전인지 확인하십시오.
💻 영향받는 소프트웨어
NVIDIA Cloud Gaming Guest Driver for Linux