🇰🇷 한글 설명
Linux 커널의 NFS 직접 쓰기 기능에서 비동기 커밋 요청 처리 중 메모리 참조 카운트 언더플로우가 발생하여 Use-After-Free 취약점이 생긴다. 일부 비동기 요청이 다음 요청 제출 전에 완료될 때 같은 nfs_direct_request 객체가 중복으로 해제되면서 refcount 경고가 반복적으로 발생한다.
💡 쉬운 설명
Linux의 네트워크 파일 공유 시스템에서 메모리 정리 과정이 중복으로 실행되어 시스템 충돌을 일으킬 수 있다. 특정 파일 작업 요청이 빠르게 완료될 때 이 문제가 자주 발생한다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
nfs: fix UAF in direct writes
In production we have been hitting the following warning consistently
------------[ cut here ]------------
refcount_t: underflow; use-after-free.
WARNING: CPU: 17 PID: 1800359 at lib/refcount.c:28 refcount_warn_saturate+0x9c/0xe0
Workqueue: nfsiod nfs_direct_write_schedule_work [nfs]
RIP: 0010:refcount_warn_saturate+0x9c/0xe0
PKRU: 55555554
Call Trace:
<TASK>
? __warn+0x9f/0x130
? refcount_warn_saturate+0x9c/0xe0
? report_bug+0xcc/0x150
? handle_bug+0x3d/0x70
? exc_invalid_op+0x16/0x40
? asm_exc_invalid_op+0x16/0x20
? refcount_warn_saturate+0x9c/0xe0
nfs_direct_write_schedule_work+0x237/0x250 [nfs]
process_one_work+0x12f/0x4a0
worker_thread+0x14e/0x3b0
? ZSTD_getCParams_internal+0x220/0x220
kthread+0xdc/0x120
? __btf_name_valid+0xa0/0xa0
ret_from_fork+0x1f/0x30
This is because we're completing the nfs_direct_request twice in a row.
The source of this is when we have our commit requests to submit, we
process them and send them off, and then in the completion path for the
commit requests we have
if (nfs_commit_end(cinfo.mds))
nfs_direct_write_complete(dreq);
However since we're submitting asynchronous requests we sometimes have
one that completes before we submit the next one, so we end up calling
complete on the nfs_direct_request twice.
The only other place we use nfs_generic_commit_list() is in
__nfs_commit_inode, which wraps this call in a
nfs_commit_begin();
nfs_commit_end();
Which is a common pattern for this style of completion handling, one
that is also repeated in the direct code with get_dreq()/put_dreq()
calls around where we process events as well as in the completion paths.
Fix this by using the same pattern for the commit requests.
Before with my 200 node rocksdb stress running this warning would pop
every 10ish minutes. With my patch the stress test has been running for
several hours without popping.
📍 영향받는 시스템
Linux 커널 (NFS 클라이언트로 파일 공유 사용)
⚔️ 공격 벡터
로컬 권한자가 NFS 직접 쓰기 작업을 반복 수행하여 메모리 언더플로우 트리거
🛡️ 대응 방법
Linux 커널을 패치가 적용된 최신 버전으로 업데이트
🔧 검증 코드
현재 커널 버전과 설치된 NFS 패키지를 확인하여 최신 패치가 적용되었는지 검증
uname -r && dpkg -l nfs-common 2>/dev/null | grep -E 'ii\s+'