🇰🇷 한글 설명
Linux 커널의 마운트 알림 코드(mnt_notify_add)에서 같은 마운트가 네임스페이스 락을 한 번 잡은 동안 두 번 큐에 추가될 수 있는 문제가 수정되었습니다. 이로 인해 notify_list가 해제된 메모리를 가리켜 use-after-free가 발생할 수 있습니다. 이 결함은 MNT_SHRINKABLE 마운트를 바인드 마운트하고 FAN_MARK_MNTNS 마크를 사용하는 조건에서 트리거될 수 있습니다.
💡 쉬운 설명
커널이 같은 마운트 정보를 중복으로 목록에 넣으면서 이미 해제된 메모리를 읽게 되는 오류입니다. 공격자가 이를 악용하면 시스템 충돌이나 권한 상승으로 이어질 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
namespace: queue a mount only once for mount notifications
mnt_notify_add() puts a mount on notify_list. It doesn't check whether
the mount is on the list already. That's fine as long as every mount is
queued at most once per namespace_sem hold. It isn't.
propagate_umount() moves a surviving overmount off a stack of mounts
that are going away and queues it as moved. shrink_submounts() and
mark_mounts_for_expiry() call umount_tree() for several mounts under a
single namespace_sem hold. So the second umount_tree() can take down
exactly the mount the first one reparented, reparent it once more and so
end up queueing it a second time.
The second list_add_tail() cuts the mounts queued in between out of the
list while the head still points at the last of them. notify_mnt_list()
then only visits that one mount and the others are freed after the grace
period with notify_list still pointing at them. Every later mount
operation on the host walks freed memory:
BUG: KASAN: slab-use-after-free in __list_add_valid_or_report
Read of size 8 at addr ffff8881003d57e0 by task notify_dq/162
__list_add_valid_or_report+0x15c/0x1a0
mnt_add_to_ns+0x322/0x890
attach_recursive_mnt.isra.0+0xf2a/0x1a00
path_mount+0x139c/0x1d40
This needs a mount with MNT_SHRINKABLE to bind from. That's what
finish_automount() creates (submounts of NFS, AFS and CIFS and the
tracefs mount below debugfs). Bind mounts inherit the flag. A mount
namespace with a FAN_MARK_MNTNS mark does the rest and root in a user
namespace can have both.
Initialize to_notify in alloc_vfsmnt() and leave a mount alone that is
queued already. mnt_notify() looks at the state the mount has when the
list is drained so a single entry per mount is enough. The move event
for a mount that is unmounted under the same hold is lost. That's fine.
The detach is what matters.
📍 영향받는 시스템
수정 이전의 Linux 커널 (CVE 식별자 기준 해당 버전 범위는 벤더 권고문으로 확인 필요)
⚔️ 공격 벡터
사용자 네임스페이스 권한을 가진 로컬 사용자가 MNT_SHRINKABLE 마운트를 바인드 마운트하고 마운트 알림을 설정한 뒤 umount 동작을 유발
🛡️ 대응 방법
배포판 벤더가 제공하는 최신 커널 보안 업데이트를 적용하고 재부팅
🔧 검증 코드
출력된 커널 버전을 배포판 보안 공지에서 해당 CVE의 수정 버전과 비교하여, 같거나 높으면 패치가 적용된 것입니다.