🇰🇷 한글 설명
Linux 커널의 mount 네임스페이스 처리에서, mnt_change_mountpoint() 함수가 이동된 마운트의 이전 부모에 대한 ->overmount 포인터를 초기화하지 않아 발생하는 취약점입니다. 해당 포인터가 해제된 마운트를 가리키게 되어 use-after-free가 발생할 수 있습니다.
💡 쉬운 설명
리눅스 커널이 파일시스템 마운트를 옮길 때 이전 위치의 참조를 정리하지 않아, 이미 삭제된 메모리를 가리키는 문제가 있습니다. 권한이 있는 공격자가 이를 악용하면 커널 메모리 손상이나 권한 상승으로 이어질 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
namespace: reset the old parent's ->overmount in mnt_change_mountpoint()
__umount_mnt() resets ->overmount of the parent when it unmounts the
mount that overmounts it. mnt_change_mountpoint() doesn't. It moves the
mount to its new parent and leaves the old one pointing at it.
For a mount that is moved beneath in attach_recursive_mnt() that doesn't
matter. The new mount has already reset ->overmount of the old parent by
the time the old top mount is moved onto it.
It matters for reparent() though. propagate_umount() moves a surviving
overmount onto the first ancestor that isn't going to be unmounted. The
mount it was taken from is unmounted immediately afterwards. If a file
descriptor keeps that unmounted mount alive ->overmount points at the
moved mount. That's a dangling pointer and UAF as the moved mount is
unmounted and freed.
do_lock_mount() follows ->overmount from the target path under
mount_lock. With a file descriptor on such a mount as the target of a
mount beneath topmost_overmount() walks into the freed mount and
do_lock_mount() takes references on whatever it finds there.
So reset ->overmount of the old parent in mnt_change_mountpoint() the
same way __umount_mnt() does. A mount's ->overmount is then always a
mount that is attached to it.
📍 영향받는 시스템
패치가 적용되지 않은 Linux 커널 버전 (마운트 네임스페이스 기능을 사용하는 대부분의 배포판)
⚔️ 공격 벡터
로컬 사용자가 마운트 네임스페이스를 조작하고 파일 디스크립터로 언마운트된 마운트를 유지하여 use-after-free 상태를 유발
🛡️ 대응 방법
배포판 벤더가 제공하는 최신 커널 업데이트를 적용하고 재부팅
🔧 검증 코드
출력된 커널 버전을 배포판 보안 공지에서 해당 CVE의 수정 버전과 비교하여, 같거나 높으면 패치가 적용된 것입니다.