🇰🇷 한글 설명
Linux 커널의 VFS(가상 파일 시스템) 계층에서 evict_inodes()와 find_inode() 및 iput() 함수 간의 레이스 컨디션(경쟁 상태) 취약점이 발견되었습니다. 이로 인해 동일한 inode에 대해 두 개의 스레드가 동시에 evict를 시도하여 커널 버그를 유발할 수 있습니다.
💡 쉬운 설명
컴퓨터가 파일을 정리하는 과정에서 두 작업이 동시에 같은 파일을 삭제하려고 시도하여 충돌이 발생하는 문제입니다. 이 충돌로 인해 시스템이 불안정해지거나 오류가 발생할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
vfs: fix race between evice_inodes() and find_inode()&iput()
Hi, all
Recently I noticed a bug[1] in btrfs, after digged it into
and I believe it'a race in vfs.
Let's assume there's a inode (ie ino 261) with i_count 1 is
called by iput(), and there's a concurrent thread calling
generic_shutdown_super().
cpu0: cpu1:
iput() // i_count is 1
->spin_lock(inode)
->dec i_count to 0
->iput_final() generic_shutdown_super()
->__inode_add_lru() ->evict_inodes()
// cause some reason[2] ->if (atomic_read(inode->i_count)) continue;
// return before // inode 261 passed the above check
// list_lru_add_obj() // and then schedule out
->spin_unlock()
// note here: the inode 261
// was still at sb list and hash list,
// and I_FREEING|I_WILL_FREE was not been set
btrfs_iget()
// after some function calls
->find_inode()
// found the above inode 261
->spin_lock(inode)
// check I_FREEING|I_WILL_FREE
// and passed
->__iget()
->spin_unlock(inode) // schedule back
->spin_lock(inode)
// check (I_NEW|I_FREEING|I_WILL_FREE) flags,
// passed and set I_FREEING
iput() ->spin_unlock(inode)
->spin_lock(inode) ->evict()
// dec i_count to 0
->iput_final()
->spin_unlock()
->evict()
Now, we have two threads simultaneously evicting
the same inode, which may trigger the BUG(inode->i_state & I_CLEAR)
statement both within clear_inode() and iput().
To fix the bug, recheck the inode->i_count after holding i_lock.
Because in the most scenarios, the first check is valid, and
the overhead of spin_lock() can be reduced.
If there is any misunderstanding, please let me know, thanks.
[1]: https://lore.kernel.org/linux-btrfs/
[email protected]/
[2]: The reason might be 1. SB_ACTIVE was removed or 2. mapping_shrinkable()
return false when I reproduced the bug.
📍 영향받는 시스템
Linux Kernel (VFS 및 btrfs 관련 구성 요소)
⚔️ 공격 벡터
로컬 공격자가 특정 파일 시스템 작업(예: btrfs 사용 중 파일 시스템 종료 및 접근)을 정밀하게 타이밍을 맞춰 수행하여 레이스 컨디션 유발
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 i_lock을 획득한 후 i_count를 재확인하도록 수정된 코드를 적용해야 합니다.
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전 이후인지 확인합니다.