🇰🇷 한글 설명
Linux 커널의 cuse 모듈에서 모듈 종료 시 대기 중인 RCU 콜백을 기다리지 않아 발생하는 취약점입니다. 모듈이 메모리에서 해제된 후 RCU 콜백이 실행되면 해제된 메모리 영역을 참조하게 되어 시스템 오류(Oops)나 정의되지 않은 동작이 발생할 수 있습니다.
💡 쉬운 설명
프로그램 부품(모듈)을 제거할 때, 아직 끝나지 않은 뒷정리 작업이 남아있어 문제가 발생합니다. 뒷정리가 끝나기 전에 부품을 먼저 치워버려서 컴퓨터가 엉뚱한 곳을 참조하다가 멈추거나 오류가 날 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
cuse: wait for pending RCU callbacks on module exit
Since commit 053fc4f755ad ("fuse: fix UAF in rcu pathwalks"),
fuse_conn_put() frees the fuse_conn through call_rcu() rather than
synchronously. For cuse, fc->release is cuse_fc_release(), which
lives in the cuse module. If the module is removed before the RCU
grace period ends, the callback jumps into freed module memory:
userspace / module unload | RCU softirq
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
close(/dev/cuse) |
cuse_channel_release() |
fuse_dev_release() |
fuse_conn_put(fch->conn) |
call_rcu(delayed_release) ------+---> callback queued
|
rmmod cuse |
cuse_exit() |
cuse_channel_destroy() |
... |
return |
|
<module text freed> |
| rcu_do_batch()
| delayed_release()
| fc->release()
| -> cuse_fc_release()
| ^^^ freed text!
The freed module text is unmapped by vfree(), so the jump into the
stale callback triggers a page-fault Oops. If the virtual address
is subsequently reused, the callback could execute unrelated code
(undefined behaviour).
Fix this by calling rcu_barrier() in cuse_exit() so that any pending
fuse_conn release callback completes before the module is removed.
📍 영향받는 시스템
Linux kernel (cuse module 사용 환경)
⚔️ 공격 벡터
로컬 사용자가 cuse 모듈을 로드한 후 특정 시점에 모듈을 제거(rmmod)하여 유도
🛡️ 대응 방법
cuse_exit() 함수 내에 rcu_barrier()를 호출하여 모든 RCU 콜백이 완료된 후 모듈이 제거되도록 커널 패치 적용
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전인지 배포판 보안 공지를 통해 확인