🇰🇷 한글 설명
Linux 커널의 NBD(Network Block Device) 드라이버에서 NBD_CLEAR_SOCK 및 NBD_CMD_RECONFIGURE 명령을 실행할 때 발생하는 Use-After-Free(UAF) 취약점입니다. recv_work 함수 내에서 설정 참조 카운트(config reference)가 적절히 유지되지 않아, 작업 스레드가 실행 중인 동안 메모리가 해제될 수 있습니다.
💡 쉬운 설명
네트워크를 통해 저장 장치를 연결하는 기능에서 메모리 관리 오류가 발생하여, 이미 사용이 끝난 메모리 영역에 접근하려 할 때 시스템 오류나 보안 문제가 생길 수 있는 결함입니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
nbd: defer config put in recv_work
There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and
NBD_CMD_RECONFIGURE:
nbd_genl_connect // conf_ref=2 (connect and recv_work A)
nbd_open // conf_ref=3
recv_work A done // conf_ref=2
NBD_CLEAR_SOCK // conf_ref=1
nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B)
close nbd // conf_ref=1
recv_work B
config_put // conf_ref=0
atomic_dec(&config->recv_threads); -> UAF
Or only running NBD_CLEAR_SOCK:
nbd_genl_connect // conf_ref=2
nbd_open // conf_ref=3
NBD_CLEAR_SOCK // conf_ref=2
close nbd
nbd_release
config_put // conf_ref=1
recv_work
config_put // conf_ref=0
atomic_dec(&config->recv_threads); -> UAF
Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the
waiter") moved nbd_config_put() to run before waking up the waiter in
recv_work, in order to ensure that nbd_start_device_ioctl() would not
be woken up while nbd->task_recv was still uncleared.
However, in nbd_start_device_ioctl(), after being woken up it explicitly
calls flush_workqueue() to make sure all current works are finished.
Therefore, there is no need to move the config put ahead of the wakeup.
Move nbd_config_put() to the end of recv_work, so that the reference is
held for the whole lifetime of the worker thread. This makes sure the
config cannot be freed while recv_work is still running, even if clear
+ reconfigure interleave.
In addition, we don't need to worry about recv_work dropping the last
nbd_put (which causes deadlock):
path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT):
connect // nbd_refs=1 (trigger recv_work)
open nbd // nbd_refs=2
NBD_CLEAR_SOCK
close nbd
nbd_release
nbd_disconnect_and_put
flush_workqueue // recv_work done
nbd_config_put
nbd_put // nbd_refs=1
nbd_put // nbd_refs=0
queue_work
path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT):
connect // nbd_refs=2 (trigger recv_work)
open nbd // nbd_refs=3
NBD_CLEAR_SOCK // conf_refs=2
close nbd
nbd_release
nbd_config_put // conf_refs=1
nbd_put // nbd_refs=2
recv_work done // conf_refs=0, nbd_refs=1
rmmod // nbd_refs=0
Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put")
📍 영향받는 시스템
Linux kernel (NBD driver 사용 환경)
⚔️ 공격 벡터
로컬 또는 원격에서 특정 NBD 명령(NBD_CLEAR_SOCK, NBD_CMD_RECONFIGURE)을 정교하게 순차적으로 실행하여 메모리 해제 유도
🛡️ 대응 방법
커널 패치(Commit 87aac3a80af5 관련 수정 사항 포함)를 적용하여 recv_work의 마지막 단계에서 config_put이 호출되도록 업데이트
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 해결된 패치 버전 이후인지 확인하십시오.