🇰🇷 한글 설명
Linux 커널의 CIFS(SMB) 클라이언트에서 Direct I/O(DIO) 사용 중 파일 언마운트 시 dentry 참조 횟수가 적절히 해제되지 않는 취약점입니다. 이로 인해 언마운트 과정에서 'busy dentry' 경고가 발생하며, 이는 지연된 파일 닫기 작업이 언마운트 프로세스보다 늦게 완료되기 때문에 발생합니다.
💡 쉬운 설명
파일을 사용 중인 상태에서 강제로 연결을 해제하려고 할 때, 시스템이 파일이 아직 사용 중이라고 착각하여 오류를 내뱉는 문제입니다. 파일 작업이 완전히 끝나기 전에 연결 해제 절차가 먼저 진행되어 발생하는 충돌입니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
smb: client: fix busy dentry warning on unmount after DIO
Commit c68337442f03 ("cifs: Fix busy dentry used after unmounting") fixed
the issue in cifs where deferred close of a file led to a dentry reference
count not being released in umount, by flushing deferredclose_wq in
cifs_kill_sb() to solve it.
However, the cifs DIO path suffers from the same busy-dentry problem caused
by a delayed dentry reference-count release:
[dio] [cifsd] [close + umount]
netfs_unbuffered_write_iter_locked
...
cifs_demultiplex_thread
netfs_unbuffered_write
cifs_issue_write
netfs_wait_for_in_progress_stream [1]
...
netfs_write_subrequest_terminated
netfs_subreq_clear_in_progress
netfs_wake_collector // wake [1]
netfs_put_subrequest
netfs_put_request
queue_work(system_dfl_wq, xxx) [2]
// dio write return cifs_close
_cifsFileInfo_put
// cfile->count 2->1
--cfile->count [3]
// umount
cifs_kill_sb
kill_anon_super
// warning triggered!
shrink_dcache_for_umount [4]
[system_dfl_wq] [5]
netfs_free_request
...
_cifsFileInfo_put
// cfile->count 1->0
--cfile->count
queue_work(fileinfo_put_wq, xxx)
[fileinfo_put_wq] [6]
cifsFileInfo_put_work
cifsFileInfo_put_final
dput
If the umount path is triggered before [5], it results warning:
BUG: Dentry 00000000eab1f070{i=9a917b66ae404fec,n=test} still in use (1)
[unmount of cifs cifs]
The existing per-inode ictx->io_count wait in cifs_evict_inode() does not
help: it lives in the inode eviction path, which runs after
shrink_dcache_for_umount() has already warned about the busy dentries.
Fix it by adding a per-superblock outstanding-rreq counter that is
incremented in cifs_init_request() and decremented in cifs_free_request().
In cifs_kill_sb(), before kill_anon_super(), wait for this counter to reach
0 - which guarantees that all cleanup_work for this sb have run and thus
all relevant cfile puts are queued on fileinfo_put_wq or serverclose_wq.
Then drain the workqueue so the dentry refs are dropped.
This is a targeted wait, not a flush of the system-wide system_dfl_wq.
📍 영향받는 시스템
Linux kernel (CIFS/SMB client with Direct I/O enabled)
⚔️ 공격 벡터
Local (사용자가 특정 파일 I/O 작업 직후 언마운트를 시도할 때 발생)
🛡️ 대응 방법
Linux 커널을 최신 버전으로 업데이트하여 cifs_kill_sb() 내의 outstanding-rreq 카운터 대기 로직이 적용된 패치를 적용하십시오.
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 커널 패치 버전 이후인지 확인하십시오.