🇰🇷 한글 설명
Linux 커널 모듈 언로드 시 kprobe 등록 검사에서 is_module_text_address()와 __module_text_address()를 순차적으로 호출하면, 두 호출 사이에 모듈 상태가 LIVE/GOING에서 UNFORMED로 변경되어 use-after-free가 발생한다. arm_kprobe()가 이미 해제된 모듈 텍스트 주소를 수정하려고 시도하게 된다.
💡 쉬운 설명
커널이 메모리 주소를 두 번 확인할 때, 첫 번째와 두 번째 확인 사이에 그 메모리가 해제되어 존재하지 않는 영역에 접근하게 된다. 로컬 공격자가 이를 악용해 시스템 충돌이나 권한 상승을 유발할 수 있다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
kprobes: Fix possible use-after-free issue on kprobe registration
When unloading a module, its state is changing MODULE_STATE_LIVE ->
MODULE_STATE_GOING -> MODULE_STATE_UNFORMED. Each change will take
a time. `is_module_text_address()` and `__module_text_address()`
works with MODULE_STATE_LIVE and MODULE_STATE_GOING.
If we use `is_module_text_address()` and `__module_text_address()`
separately, there is a chance that the first one is succeeded but the
next one is failed because module->state becomes MODULE_STATE_UNFORMED
between those operations.
In `check_kprobe_address_safe()`, if the second `__module_text_address()`
is failed, that is ignored because it expected a kernel_text address.
But it may have failed simply because module->state has been changed
to MODULE_STATE_UNFORMED. In this case, arm_kprobe() will try to modify
non-exist module text address (use-after-free).
To fix this problem, we should not use separated `is_module_text_address()`
and `__module_text_address()`, but use only `__module_text_address()`
once and do `try_module_get(module)` which is only available with
MODULE_STATE_LIVE.
📍 영향받는 시스템
CONFIG_KPROBES와 CONFIG_MODULES가 활성화된 모든 Linux 커널 시스템 (커널 6.x 이전 버전)
⚔️ 공격 벡터
로컬 공격자가 악의적 커널 모듈을 로드/언로드하여 kprobe 등록 중 race condition 악용 또는 모듈 상태 변경 활용
🛡️ 대응 방법
Linux 커널을 CVE-2024-35955 패치가 적용된 버전으로 업그레이드 또는 배포판 보안 업데이트 적용
🔧 검증 코드
CONFIG_KPROBES=y로 표시되면 시스템이 kprobes를 활성화했으므로 취약할 수 있으며, uname -r로 커널 버전을 확인하여 패치 적용 여부를 판단해야 한다
cat /boot/config-$(uname -r) 2>/dev/null | grep CONFIG_KPROBES