요약
설명: Januscape(CVE-2026-53359)는 리눅스 커널의 KVM/x86 섀도 MMU에서 발생하는 ‘use-after-free’ 취약점입니다. 악의적인 게스트는 KVM이 더 이상 구축 중인 매핑과 일치하지 않는 캐시된 섀도 페이지를 재사용하도록 유도할 수 있으며, 이로 인해 KVM이 나중에 해제할 메모리를 가리키는 오래된 역매핑 항목이 남게 됩니다. 자세한 내용 보기 →
영향: 확실하게 확인된 공개된 결과는 호스트 시스템의 충돌입니다. 공개된 연구에 따르면, 게스트에서 호스트로의 완전한 탈출(full guest-to-host escape)이 가능하며, 이는 호스트에서 루트 권한으로 실행되는 악성 게스트 내부의 코드를 통해 이루어집니다. 저희는 AlmaLinux 9 및 Ubuntu 24.04에서 호스트 메모리 손상 및 서비스 거부(DoS) 원시 기능을 독립적으로 확인했으나, 완전한 탈출 체인은 재현하지 못했습니다. /dev/kvm에 대한 접근 권한이 모든 사용자에게 공개된 RHEL 계열 시스템에서는, 동일한 버그가 로컬에서 루트 권한으로의 권한 상승을 유발합니다. 자세한 내용으로 이동 →
상태: 업스트림에서 수정됨 (커밋 81ccda30b4e8, 2026년 6월 메인라인에 병합됨). NVD는 2026년 7월 4일에 CVE를 공개했으며, 7월 6일에 공개 제한이 해제되었습니다. 이 취약점은 kvmCTF 대회에 제출된 제로데이 취약점이었으나, 현재 방어 측 입장에서는 공개된 개념 증명(PoC)이 있는 N-데이 취약점입니다. 자세한 내용으로 이동 →
중요도: NVD는 본 문서 발행 시점에 CVSS 점수를 부여하지 않았습니다. 점수가 없는 것이 영향도가 낮다는 것을 의미하지는 않습니다. 내부적으로 점수를 ‘높음’으로 평가하고, 색상 표시가 나타날 때까지 기다리지 마십시오. 전체 버전으로 이동 →
영향을 받는 대상: 게스트에 중첩 가상화를 노출하는 KVM/x86 호스트(인텔 및 AMD). 이 탈출 경로에는 게스트 루트 권한 외에도 한 가지 요소가 더 필요합니다. 바로 중첩 가상화입니다. 자세한 내용으로 이동 →
관련 취약점: Januscape를 완전히 차단하려면 두 번째 수정 사항인 CVE-2026-46113이 필요합니다. 이전 취약점만 패치해서는 Januscape를 막을 수 없습니다. 자세한 내용으로 이동 →
지금 바로 다음 조치를 취하십시오: 영향을 받은 KVM 호스트에 수정된 커널을 적용하거나 재부팅 없이 적용 가능한 패치를 적용하십시오. 가상 머신을 실행하지 않는 호스트는 KVM 모듈을 언로드하고 차단할 수 있습니다. 가상 머신을 실행하지만 중첩 가상화가 필요 없는 호스트는 중첩 가상화를 비활성화해야 하며, 이렇게 하면 ‘untrusted-guest’ 탈출 경로가 제거됩니다. 두 가지 기능이 모두 필요한 호스트의 경우 설정만으로는 문제를 해결할 수 없습니다. 자세한 내용으로 이동 →
모든 VM을 재부팅하지 않고 KVM 호스트에 패치를 적용해야 하나요?
KernelCare는 다운타임, 워크로드 중단 또는 긴급 유지보수 시간 없이 리눅스 커널 보안 패치를 적용합니다.
KernelCare 현황: 2026년 7월 7일현재 , CVE-2026-53359 및 이에 필수적으로 수반되는 CVE-2026-46113을 모두 다루는 재부팅 불필요 패치가 여러 커널 계열에 대해 함께 제공되고 있으며, 추가 패치들도 활발히 개발 중입니다. 전체 릴리스 현황 및 K-태그는 아래에 나열되어 있습니다.
자세한 내용
Januscape는 가상화의 핵심 약속을 정면으로 비판한다.
게스트 VM은 해킹당했거나, 고객이 제어하거나, 구형이거나, 의도적으로 악의적이거나, 단순히 잘못 구성된 상태일 수 있습니다. 어떤 경우든 게스트 VM이 호스트의 메모리에 접근해서는 안 됩니다. KVM의 역할은 이러한 격리를 유지하면서 게스트 메모리를 안전하게 변환하는 것입니다. Januscape는 이러한 변환 과정의 내부 관리 체계를 무너뜨립니다.
이 버그는 arch/x86/kvm/mmu/mmu.c 파일 내 KVM 섀도 MMU에 존재합니다. 이 코드는 게스트가 사용하는 주소를 호스트가 승인한 메모리에 매핑하는 호스트 측 페이지 테이블 구조를 관리합니다. 특정 순서로 게스트 매핑이 변경되는 상황에서, KVM은 기록된 역할이 구축 중인 매핑과 더 이상 일치하지 않음에도 불구하고 기존 섀도 페이지를 재사용합니다. 이러한 재사용으로 인해 KVM이 나중에 해제할 구조를 가리키는 역매핑 항목이 남게 되며, 이후 역매핑 탐색 과정에서 해제된 페이지에 대한 참조가 발생합니다.
먼저 한 가지 명확히 해둘 점은, 이것이 누가 취약점에 노출되는지를 결정하기 때문입니다. 이는 전통적인 의미의 데이터 경합(data race)이 아니며, 유사한 결함과도 다릅니다. 커널은 Januscape를 예기치 못한 섀도우 페이지 역할로 인해 발생하는 ‘use-after-free’ 결함으로 분류합니다. 이 결함이 발동되는 과정은 게스트의 자체 페이지 탐색(page walk) 외부에서 비동기적으로 게스트 매핑을 변경하는 것이므로, 해당 창(window)을 공략하려면 정확한 타이밍이 필요합니다. 하지만 근본 원인은 비교 연산 누락이지, 잠금(lock) 버그가 아닙니다. 이 차이점을 명심하십시오. 수정 및 완화 조치는 바로 이 차이에서 비롯되기 때문입니다.
Januscape의 작동 원리
대략적으로 말하자면:
[Guest with root + nested virtualization exposed]
│ forces KVM back through the legacy shadow MMU
▼
[Guest creates a large 2 MB mapping → KVM builds a direct shadow page]
│
▼
[Guest rewrites the mapping to a 4 KB page-table path]
│ new mapping needs a non-direct (direct=0) page
▼
[kvm_mmu_get_child_sp() reuses the old direct page – gfn matches, role NOT compared]
│
▼
[Cleanup computes the wrong frame number → reverse-map entry not removed]
│
▼
[Shadow page freed; stale reverse-map entry left behind]
│ later rmap walk (dirty logging / MMU-notifier invalidation)
▼
[Use-after-free write of a fixed marker into freed memory]
▼
[Host crash (public PoC) → or guest-to-host escape, root on host (withheld exploit)]
해당 과정을 자세히 살펴보면, 이 시퀀스는 2MB 규모의 매핑을 설명하는 게스트 페이지 디렉터리 항목으로 시작됩니다. KVM은 4KB 크기의 개별 항목 512개를 포괄하는 kvm_mmu_page를 생성하며, 게스트 매핑이 연속된 대용량 페이지이므로 섀도 페이지를 ‘direct’로 표시합니다.
그러면 게스트의 정상적인 실행 흐름 밖에서 매핑이 변경됩니다. 이제 동일한 페이지 디렉터리 항목이 대용량 페이지가 아닌, 개별 4KB 매핑을 포함하는 또 다른 페이지 테이블을 가리키게 됩니다. KVM은 이러한 구조를 위해 다른 종류의 섀도 페이지가 필요합니다. 원래 섀도 페이지는 ‘직접(direct)’ 역할을 수행하지만, 새로운 매핑에는 ‘비직접(non-direct)’ 역할이 필요합니다. 취약점이 있는 kvm_mmu_get_child_sp() 경로는 기존 페이지를 재사용하기로 결정하기 전에 해당 전체 역할을 비교하지 않습니다. 프레임 번호가 일치하므로 페이지가 승인되고, KVM은 새로운 리프 항목을 설치하며, 새로운 탐색 과정을 통해 확인된 프레임에 대한 역매핑 항목을 기록합니다.
이 문제는 정리 과정에서 드러납니다. 재사용된 부모 페이지가 여전히 직접(direct) 페이지라고 주장하기 때문에, KVM은 저장된 섀도 변환을 사용하는 대신 새로운 4KB 항목에 대한 프레임을 sp->gfn + index로 계산합니다. 그런 다음 잘못된 프레임 번호로 리버스 맵 항목을 검색하게 되며, 이를 제거하는 데 실패합니다. 섀도 페이지는 해제되지만, 오래된 리버스 맵 항목은 그대로 남아 있게 됩니다. 이후 해당 리버스 맵을 탐색하는 모든 작업은 해제된 페이지 내의 항목을 참조하게 됩니다. 커널 기록에 따르면, 이러한 현상을 유발하는 작업으로 더티 로깅(dirty logging)과 MMU-notifier 무효화(MMU-notifier invalidation)가 꼽힙니다.
공개된 PoC와 공개되지 않은 익스플로잇을 모두 설명해 주는 세부 사항이 하나 있습니다. 테어다운 과정에서 KVM은 현재 재할당되었을 수도 있는 메모리 영역에 고정된 마커 상수를 기록합니다. 이는 명백한 ‘사용 후 해제(use-after-free)’ 쓰기이지만, 일정한 제약이 따릅니다. 즉, 공격자가 유용한 커널 객체와 정렬시켜야 하는 주소에 고정된 값이 기록되기 때문입니다. 이러한 정렬을 확실하게 맞추기는 어렵기 때문에, 공개된 코드는 호스트를 다운시키는 데 그치며 완전한 탈출 코드는 공개되지 않은 것입니다.
게스트는 중첩 가상화를 통해 이 코드에 도달합니다. 하드웨어 페이징(인텔의 EPT, AMD의 NPT)을 사용하여 게스트를 실행하는 최신 호스트에서는 일반적으로 소프트웨어 섀도 MMU가 작동하지 않습니다. 중첩 가상화를 노출시키는 것이야말로 KVM을 레거시 섀도 MMU로 되돌아가게 하는 요인이며, 바로 그곳에 Januscape가 위치합니다. 이것이 호스트가 최신형으로 보일지라도 여전히 이 문제의 적용 범위에 확실히 포함될 수 있는 이유입니다.
확인된 사항
저희의 테스트 결과, Enterprise Linux 커널과 Ubuntu 24.04 모두에서 해당 취약점에 도달할 수 있음이 확인되었습니다. 호스트 DoS 및 메모리 손상 현상을 재현했습니다. 다만, 연구자가 공개하지 않은 익스플로잇인 ‘엔드투엔드 이스케이프’는 실행하지 않았습니다.
커널 5.14.0-687.5.3.el9_8이 탑재된 AlmaLinux 9에서, 트리거로 인해 pte_list_remove() 함수에서 치명적인 커널 버그가 발생했습니다. 활성 프로세스가 qemu-kvm인 상태에서 호스트가 몇 초에서 몇 분 내에 패닉 상태에 빠졌습니다. 이는 테스트된 커널에서 게스트에 의해 유발된 신뢰할 수 있는 호스트 서비스 거부(DoS) 현상입니다.
커널 6.8.0-111-generic이 적용된 Ubuntu 24.04에서는 동일한 데이터 손상이 발생했을 때 즉시 패닉이 발생하기보다는 경고가 표시되었습니다. 커널은 kvm_mmu_page_set_translation()에서 GFN 불일치를 보고했으며(근본 원인인 프레임 혼동이 드러난 것), 이어서 하류에서 pte_list_remove() 경고가 발생했습니다. 이 Ubuntu 빌드에서는 해당 일관성 검사가 치명적인 BUG 검사가 아닌 경고 등급으로 처리되기 때문에 호스트는 정상적으로 작동할 수 있었으며, 손상된 섀도우 MMU 상태(Tainted: G W)로 계속 실행되었습니다.
경고가 발생했다고 해서 안전한 것은 아닙니다. 이는 호스트에서 관리하는 번역 상태가 일관성을 잃었고, 시스템이 자체 어설션(assertion)을 간신히 넘긴 것을 의미합니다. 제어된 크래시 덤프 수집을 위해, 경고 등급의 재현 사례를 치명적인 오류로 설정할 수 있습니다:
sudo sysctl kernel.panic_on_warn=1
이는 테스트 및 vmcore 지원 기능입니다. 완화 조치는 아닙니다.
‘Upstream Fix’의 변경 사항
이 수정 사항은 KVM이 섀도 페이지를 재사용하기 전에 누락되었던 역할 검사를 추가합니다. 패치 적용 전에는 일치하는 게스트 프레임 번호만으로도 기존 페이지를 수용할 수 있었습니다. 패치 적용 후에는 kvm_mmu_get_child_sp() 함수가 페이지의 전체 역할(role.word)과 프레임 번호를 비교하여, 두 값이 모두 일치할 때만 페이지를 재사용합니다. 역할이 호환되지 않을 경우, KVM은 오래된 해석을 그대로 이어가는 대신 기존 항목을 삭제하고 올바른 섀도 페이지를 생성합니다. 이 패치는 KVM 유지보수 담당자인 Paolo Bonzini와 Sean Christopherson이 작성했습니다.
개념적으로:
Before: matching gfn → reuse shadow page → role mismatch ignored → stale reverse map → use-after-free
After: matching gfn → compare role.word → reject incompatible page → zap old entry → build correct page
업스트림 Januscape 수정 사항은 커밋 81ccda30b4e83d8f5cc4fd50503c44e3a33abfeb입니다. 이와 관련된 CVE-2026-46113 수정 사항은 커밋 0cb2af2ea66ad8ff195c156ea690f11216285bdf입니다. 각각 서로 다른 stale-shadow-page 문제를 해결하므로, 두 수정 사항 모두 패치된 커널에 포함되어야 합니다.
벤더 및 rebootless-patch 기록에서 이를 항상 별도로 표기하는 것은 아닙니다. 일부 초기 KernelCare 빌드에서는 Januscape 역할 수정 사항을 CVE-2026-46113 라벨 아래에 CVE 번호가 부여되지 않은 부가 항목으로 포함시켰기 때문에, 별도의 CVE-2026-53359 문자열이 없다고 해서 그 자체로 해당 역할 수정 사항이 누락되었다고 볼 수는 없습니다.
관련 취약점: CVE-2026-46113
Januscape는 단독으로 발생한 것이 아닙니다. 이 문제가 수정되기 전에, 커널 개발자들은 MMU의 동일한 부분에서 발생한 또 다른 KVM/x86 섀도우 페이징(shadow-paging) 유즈-애프터-프리(use-after-free) 취약점인 CVE-2026-46113을 먼저 해결했습니다. 두 수정 사항은 서로 다른 취약점을 다루고 있으며, 호스트 시스템에는 두 가지 수정 사항이 모두 필요하기 때문에, 이 두 가지 결함은 함께 논의되어야 하지만 결코 혼동되어서는 안 됩니다.
CVE-2026-46113은 KVM이 잘못된 게스트 프레임 번호를 위해 생성된 섀도 페이지를 재사용할 때 발생합니다. VM 항목 간에 게스트 매핑이 변경되더라도 KVM은 원래 매핑을 위해 생성된 섀도 페이지를 계속 사용하며, 새로운 페이지 테이블 항목이 KVM이 나중에 정리 과정에서 검색하는 범위 외부의 프레임 아래에 기록됩니다. 정리 과정에서 이 항목이 누락됩니다. 섀도 페이지는 해제되지만, 오래된 역매핑 항목은 그대로 남아 있습니다. 이후 역매핑 탐색 과정에서 해제된 페이지에 대한 참조가 발생합니다.
CVE-2026-46113 수정 사항(커밋 0cb2af2ea66a)에서는 게스트 프레임 번호 검사 기능이 추가되었습니다. KVM이 기존 페이지가 잘못된 프레임에 속해 있음을 감지하면, 해당 항목을 재사용하지 않고 삭제합니다. Januscape는 이러한 검사만으로는 충분하지 않음을 보여주었습니다.
Januscape 경로에서는 프레임 번호가 올바르게 표시될 수 있습니다. 불일치는 섀도 페이지의 역할에 있습니다:
- 기본 매핑은 2MB 크기의 매핑에 대해 직접 섀도 페이지를 생성합니다(direct=1).
- 게스트는 해당 매핑을 하위 레벨 페이지 테이블을 가리키도록 변경합니다.
- 새 경로에는 4KB 매핑을 위한 비직접 섀도 페이지가 필요합니다(직접=0).
- KVM은 일치하는 프레임 번호를 찾아 기존 페이지를 재사용합니다.
- 프레임은 일치하지만, 페이지에 대한 해석은 일치하지 않습니다.
CVE-2026-46113은 잘못된 프레임 관련 문제를 해결했습니다. Januscape는 잘못된 역할 관련 문제를 해결했습니다. 앞서 언급된 수정 사항은 배경 정보일 뿐이며, Januscape야말로 이 기사에서 다루는 취약점입니다. 앞서 언급된 패치만 적용한다고 해서 Januscape 문제가 해결되는 것은 아닙니다.
누가 영향을 받나요?
Januscape는 KVM/x86 섀도우 MMU를 사용하는 리눅스 시스템에 영향을 미칩니다. 취약한 코드가 kvm_intel이나 kvm_amd 중 한 곳에만 있는 것이 아니라 공유된 KVM/x86 MMU 로직에 위치해 있기 때문에, 인텔 및 AMD 호스트 모두에 해당됩니다. 연구원은 아키텍처별 페이지 테이블 비트만 교체하는 방식으로 두 호스트 모두에서 동일한 트리거를 시연했습니다. 특정 호스트가 얼마나 취약한지는 몇 가지 차이점에 따라 결정됩니다.
중첩 가상화를 통해 게스트를 실행하는 KVM 하이퍼바이저. 최우선 순위. 자체 VM 내에서 루트 권한을 가진 악성 또는 침해된 게스트는 중첩 가상화를 통해 취약한 호스트 커널 경로에 접근할 수 있습니다. 이는 ‘게스트-호스트 탈출’ 시나리오로, 단 하나의 임대 인스턴스만으로도 물리적 호스트를 다운시키거나, 익스플로잇을 유보해 둔 상태에서 동일한 위치에 있는 다른 게스트들을 장악할 수 있습니다. 저희 연구실의 재현 환경에서는 게스트가 원시 VMX/SVM 상태를 제어하는 모듈을 로드하는데, 이것이 바로 중첩 가상화 경로입니다.
게스트를 실행하지만 중첩 가상화를 노출하지 않는 KVM 호스트입니다. 해당 게스트의 경우 소프트웨어 섀도 MMU가 강제적으로 작동하지 않기 때문에, 게스트에서 호스트로 이어지는 공격 경로의 노출 위험이 낮습니다. 이 기능을 활용하기 전에 중첩 가상화가 실제로 비활성화되어 있는지 확인하십시오.
KVM을 사용할 수 있지만 실행 중인 가상 머신이 없는 호스트입니다. 신뢰할 수 없는 로컬 사용자가 /dev/kvm을 열고 KVM을 직접 제어할 수 있는 경우, 이러한 호스트에서도 로컬 경로가 노출될 수 있습니다. KVM을 사용하지 않는다면 모듈을 언로드하고 차단하십시오.
컨테이너 및 CloudLinux LVE. 일반 컨테이너는 자동으로 KVM에 접근할 수 있는 권한을 갖지 않습니다. 컨테이너 및 LVE 환경은 단순히 호스트 커널을 공유한다는 이유만으로 취약한 것은 아닙니다. 보안 노출 여부는 컨테이너가 /dev/kvm에 접근할 수 있는지, QEMU를 제어할 수 있는지, 또는 중첩 가상화를 사용할 수 있는지에 따라 달라집니다. 당사는 이러한 환경을 테스트하지 않았으며, 단순히 호스트 커널을 상속받았다는 이유만으로 안전하다고 단정하지 않습니다. 실제 장치 및 권한 구성을 확인하시기 바랍니다.
엔터프라이즈 커널 버전. uname -r 명령어 결과만으로 취약점 노출 여부를 판단하지 마십시오. 엔터프라이즈 배포판은 KVM 관련 변경 사항을 이전 버전의 베이스라인으로 역포트하므로, 5.14 기반 EL9 커널에는 해당 MMU 로직이 포함되어 있는 반면, 버전 번호상으로는 더 최신인 커널에는 이미 해당 수정 사항이 적용되었을 수 있습니다. 정확한 실행 중인 커널에 대해서는 공급업체의 수정 사항, KernelCare 지원 범위 또는 소스 패턴을 확인하십시오.
여기서 발생하는 버전 함정은 일반적인 경우와 반대 방향으로 작용합니다. “우리 커널이 너무 오래되었다”는 것이 아니라, “우리 하드웨어가 너무 새롭다”는 것입니다. EPT나 NPT를 사용하는 호스트는 중첩 가상화를 노출하고 게스트를 16년 전의 섀도우 MMU 코드를 통해 은밀하게 다시 라우팅하기 전까지는 최신식이고 안전하다고 느껴집니다. 호스트가 무엇을 노출하는지에 근거하여 판단해야지, 호스트가 구동되는 실리콘 자체를 기준으로 판단해서는 안 됩니다.
KVM 공격 표면 확인하기
KVM 모듈이 로드되었는지 확인하세요:
lsmod | grep -E '^kvm|kvm_(intel|amd)'
KVM 장치가 있는지, 그리고 누가 해당 장치에 접근할 수 있는지 확인하십시오:
ls -l /dev/kvm
실행 중인 QEMU/KVM 워크로드를 확인합니다:
pgrep -a -f 'qemu-system|qemu-kvm'
중첩 가상화가 활성화되어 있는지 확인하십시오:
cat /sys/module/kvm_intel/parameters/nested # Intel
cat /sys/module/kvm_amd/parameters/nested # AMD
libvirt로 관리되는 호스트의 경우:
virsh list --all
이 명령어들은 KVM이 노출되어 있는지, 사용 중인지, 중첩 가상화를 노출하고 있는지 여부를 알려줍니다. 하지만 이 명령어들은 Januscape에 패치가 적용되었는지 여부를 확인해 주지는 않습니다.
지금 바로 위험을 줄이세요
여기에는 실질적인 구성상의 완화 조치가 있으며, 각각은 특정 공격 경로를 차단합니다. 그 어떤 조치도 모든 공격 경로를 차단하지는 않는데, 바로 이것이 핵심입니다.
가상 머신을 실행하지 않는 호스트. 시스템에 KVM이 필요하지 않은 경우, 모듈을 언로드하고 로딩을 차단하십시오. blacklist 명령어만으로는 명시적 로딩이나 의존성으로 인한 로딩을 막을 수 없으므로, 단순한 blacklist 명령어 대신 install … /bin/false를 사용하십시오.
# unload now (fails if a VM is running, in which case this host isn't a candidate)
sudo modprobe -r kvm_intel kvm # kvm_amd on AMD hardware
# prevent load on boot
printf 'install kvm_intel /bin/false\ninstall kvm_amd /bin/false\n' \
| sudo tee /etc/modprobe.d/disable-kvm.conf
lsmod | grep kvm 명령어를 실행했을 때 결과가 나오지 않고, ls /dev/kvm 명령어를 실행했을 때 해당 파일이 없다고 표시되는지 확인하십시오. 원상복구하려면 /etc/modprobe.d/disable-kvm.conf 파일을 삭제하고 modprobe kvm_intel (또는 kvm_amd) 명령어를 실행하거나, 시스템을 재부팅하십시오.
가상 머신을 실행하지만 중첩 가상화가 필요하지 않은 호스트. 이는 패치를 적용하기 전까지 취할 수 있는 가장 강력한 완화 조치입니다. 중첩 가상화를 비활성화하면 게스트에서 호스트로 이어지는 경로가 제거되는데, 이는 섀도 MMU가 중첩 게스트에서만 작동하기 때문입니다:
# Intel
echo 'options kvm_intel nested=0' | sudo tee /etc/modprobe.d/disable-nested-virt.conf
# AMD
echo 'options kvm_amd nested=0' | sudo tee /etc/modprobe.d/disable-nested-virt.conf
이 변경 사항은 KVM 모듈이 재로드된 후(이때는 실행 중인 VM이 없어야 함) 또는 재부팅 후에 적용됩니다. `cat /sys/module/kvm_intel/parameters/nested` 명령을 실행하여 결과가 N 또는 0으로 표시되는지 확인하십시오.
VM 및 중첩 가상화를 유지해야 하는 RHEL 계열 호스트의 경우, 해당 배포판에서는 /dev/kvm이 누구나 접근할 수 있는 권한(모드 0666)으로 제공되는데, 이로 인해 권한이 없는 로컬 사용자도 이 버그를 직접 악용할 수 있습니다. 권한을 강화하십시오:
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0660"' \
| sudo tee /etc/udev/rules.d/65-kvm.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
`ls -l /dev/kvm` 및 `getent group kvm` 명령어를 통해 확인하고, KVM이 필요한 계정만 kvm 그룹에 추가하십시오. 이렇게 하면 비특권 로컬 공격 경로를 차단할 수 있습니다. 다만, 호스트 장치 권한과 무관하게 승인된 QEMU 프로세스를 통해 섀도우 MMU에 접근하는 악의적인 게스트는 막을 수 없습니다.
결정적인 순간입니다. 호스트에 게스트가 실행되고 있지 않다면, KVM을 언로드하고 차단하십시오. 중첩 가상화가 필요 없는 게스트를 실행 중인 경우, 지금 즉시 중첩 가상화를 비활성화하고 평소와 같은 주기로 패치를 적용하십시오. 신뢰할 수 없는 게스트를 실행 중이며 중첩 가상화가 필요한 경우(다중 테넌트 클라우드, 호스팅, 중첩 VM을 빌드하는 CI 등)는 어떤 구성 변경으로도 완전히 보호받을 수 없으므로, 재부팅 없이 적용 가능한 패치나 수정된 커널을 우선 순위 목록의 맨 앞으로 이동시키십시오. 또한 경고만 발생하는 재현 사례는 안전성을 입증하는 증거가 아니라, 취약점이 노출되었음을 확인하는 것으로 간주하십시오.
탐지
Januscape는 디스크상에 신뢰할 만한 흔적을 남기지 않습니다. KVM이 섀도 페이지 테이블과 역매핑을 관리하는 동안 호스트 커널 메모리에서 손상이 발생하기 때문에, 취약한 상태가 유발된 후에도 파일 무결성 검사 도구는 정상으로 나타날 수 있습니다. 이로 인해 탐지는 행동 기반 방식으로 전환되며, 다음의 각 항목은 단서일 뿐, 확실한 증거는 아닙니다.
- arch/x86/kvm/mmu/mmu.c 파일에서 발생하는 커널 버그나 경고, 특히 pte_list_remove()와 관련된 것.
- GFN 불일치 메시지 또는 kvm_mmu_page_set_translation()에서 발생하는 경고 – 메모리 해제 전에 역할 및 프레임 혼동이 드러나기 시작함.
- qemu-kvm 또는 qemu-system-*가 활성화된 상태에서 호스트가 비정상적으로 작동하거나 반복적으로 중단되지만, 이에 상응하는 하드웨어 오류는 발생하지 않습니다.
- KVM MMU 경고로 인해 W 태그가 부여된 커널.
- 예상치 못한 곳에서 중첩 가상화 활동이 감지되거나, 평소와 다른 계정이나 프로세스가 /dev/kvm에 접근하는 경우.
- KVM-MMU 불안정 현상이 급격히 발생한 직후, 이에 상응하는 sudo 명령어나 로그인 기록이 없는 상태에서 로컬 호스트 계정이나 서비스가 권한을 획득하는 경우.
최근 커널 메시지 확인:
journalctl -k --since "24 hours ago" \
| grep -Ei 'kvm|mmu|gfn|pte_list_remove|BUG|WARNING'
현재 부팅 상태를 확인하십시오:
dmesg -T | grep -Ei 'kvm|mmu|gfn|pte_list_remove|BUG|WARNING'
이러한 메시지가 없다고 해서 호스트에 패치가 적용되었다고 단정할 수는 없습니다. 공격자는 일관성 검사를 우회할 수 있으며, 취약점이 있는 경로가 아직 실행되지 않았을 수도 있습니다. 노출된 호스트에서 신뢰할 수 없는 게스트가 실행 중이고 KVM-MMU 불안정 현상이 관찰된다면, 게스트 파일 해시가 정상이라고 해서 호스트에 문제가 없다고 단정하기보다는 호스트를 면밀히 조사해야 합니다(예: 새로 생성된 계정, 변경된 인증 구성, 호스트에서 예상치 못한 서비스 실행 등).
Januscape가 중요한 이유
Januscape는 로컬 커널 권한 상승(LPE) 버그와는 다른 유형의 문제입니다. 일반적인 로컬 LPE의 경우, 공격자가 호스트에서 이미 코드 실행 권한을 확보하고 있어야 합니다. 반면 게스트 탈출(guest escape)은 KVM이 이를 차단해 줄 것이라는 전제 하에, 조직이 가상 머신(VM) 내에서 의도적으로 실행을 허용한 코드에서 시작됩니다. 바로 그 전제를 무너뜨리는 것이 이 사건의 핵심입니다.
그렇기 때문에 이 문제는 게스트 격리가 핵심인 분야에서 가장 심각한 영향을 미칩니다. 여기에는 퍼블릭 및 프라이빗 클라우드, 호스팅 제공업체, 멀티테넌트 클러스터, CI 및 빌드 인프라, 보안 연구 환경, 개발자 클라우드, 그리고 고객이 제어하는 VM을 실행하는 모든 플랫폼이 포함됩니다. 이 문제의 근본적인 가정이 오랫동안 지속되어 왔다는 점이 그 범위를 더욱 넓혀줍니다. 이러한 현상은 2010년으로 거슬러 올라가며 여러 세대의 엔터프라이즈 커널을 거쳐 이어져 왔기 때문에, “우리는 최신 배포판을 사용한다”는 주장은 변명이 될 수 없습니다.
오판하기 쉬운 이유가 바로 이것이 위험한 이유이기도 합니다. 세 가지 그럴듯한 신호가 모두 “안전”을 가리키지만, 모두 오해를 불러일으킵니다. 하드웨어 EPT나 NPT는 섀도우 MMU를 퇴출시킨 것처럼 보이지만, 중첩 가상화는 게스트를 다시 그 속으로 끌어들입니다. GFN 수정 사항(CVE-2026-46113)은 MMU의 이 구석을 막은 것처럼 보이지만, 실제로는 결함의 다른 절반만 해결했을 뿐 나머지 부분은 여전히 노출된 채로 남겨두었습니다. 또한, 자신이 소유한 시스템만 다운시키는 PoC는 무해한 자체 DoS처럼 보일 수 있지만, 사실 그 다운 현상은 한계치가 아니라 공개 시연에 불과합니다. 이 중 어느 하나라도 신뢰한다면, 취약한 호스트를 안전하다고 판단하게 될 것입니다.
CVE-2026-46113과의 연관성은 잘못된 확신을 불러일으키는 가장 큰 원인입니다. 이전에 발생한 예상치 못한 GFN use-after-free 취약점을 패치한 팀은 섀도 페이징 문제도 해결되었다고 결론지을 수 있습니다. 하지만 그렇지 않습니다. 이전 수정 사항은 KVM이 올바른 프레임을 찾았는지 여부를 확인하는 데 그쳤습니다. Januscape는 KVM이 올바른 유형의 섀도 페이지를 찾았는지까지 검증해야 한다는 사실을 보여주었습니다. 한 가지 조건만 충족되는 것으로는 충분하지 않았으며, 하나의 CVE가 해결되었다고 해서 두 가지 문제가 모두 해결된 것은 아닙니다.
우선순위별 개선 조치 체크리스트
- 이 문제를 CVE-2026-46113이 아닌 CVE-2026-53359(Januscape)로 추적하십시오.
- 영향을 받는 호스트에 Januscape 수정 사항과 관련 CVE-2026-46113 수정 사항이 모두 적용되었는지 확인하십시오. 두 가지 모두 필수입니다.
- KVM 모듈이 로드되어 있거나, /dev/kvm이 존재하거나, 활성 QEMU 워크로드가 있는 호스트를 식별하고, 중첩 가상화를 지원하는 호스트에 플래그를 지정합니다.
- 다중 테넌트 호스트와 중첩 가상화가 활성화된 상태에서 신뢰할 수 없는 게스트를 실행 중인 모든 호스트를 우선순위로 지정하십시오.
- 가상화를 사용하지 않는 호스트에서는 KVM을 완전히 비활성화하십시오.
- 필요하지 않은 곳에서는 중첩 가상화를 비활성화하십시오. 이렇게 하면 신뢰할 수 없는 게스트의 탈출 경로가 제거됩니다.
- RHEL 계열 호스트에서 /dev/kvm에 대한 접근 권한을 신뢰할 수 있는 계정과 kvm 그룹으로 제한하십시오. 이는 로컬 비특권 공격 경로만 차단할 뿐, 악의적인 게스트는 차단하지 못합니다.
- AMD 호스트를 명시적으로 확인하십시오. 인텔 전용 테스트에서 문제가 발견되지 않은 경우에도 AMD 호스트는 영향을 받습니다.
- 커널 버전만 보고 안전하다고 단정하지 말고, 경고만 발생하는 재현 사례도 노출로 간주하십시오.
- KVM GFN 경고, pte_list_remove() 오류, 원인 불명의 호스트 패닉을 찾아내고, 게스트 파일 해시 값이 정상이라고 해서 이를 호스트에 대한 충분한 증거로 간주해서는 안 됩니다.
- 고정된 벤더 커널을 적용한 후 시스템을 재부팅하거나, 현재 실행 중인 커널에 맞는 KernelCare 재부팅 불필요 패치를 사용하되, 재부팅이 가장 어려운 호스트를 우선적으로 처리하십시오.
- 빌드 날짜에만 의존하지 말고, 두 수정 사항 모두에 대해 CVE가 명시적으로 포함되었는지 확인하십시오.
재부팅 없는 패치 적용
Januscape는 수정된 패키지가 출시된 후에도 오랫동안 취약점이 노출된 채로 남아 있는 유형의 하이퍼바이저 버그입니다. 패키지를 설치하는 것은 단지 첫 단계에 불과합니다. 호스트는 여전히 대체 커널로 부팅해야 하며, KVM 클러스터의 경우 이는 노드 부하 분산, 게스트 마이그레이션, 테넌트 조정, 용량 여유 확보, 유지보수를 위한 서버 교대 등을 의미합니다. 이러한 제약 조건들로 인해 알려진 게스트 탈출 취약점이 수주 또는 수개월 동안 잔존 노출로 이어질 수 있으며, 이러한 부담은 위험에 가장 많이 노출된 바로 그 멀티테넌트 호스트에서 가장 크게 나타납니다.
이 변경 사항은 재부팅 없이 적용할 수 있는 패치의 좋은 후보입니다. MMU 오류 및 역매핑 경로에 대한 사소한 수정이며, 적용 후 유지되어야 할 영구적인 상태가 없기 때문입니다. KernelCare는 Januscape 역할 수정(81ccda30b4e8)과 이에 수반되는 GFN 수정(0cb2af2ea66a)이라는 두 가지 필수 수정 사항을 모두 실행 중인 커널에 함께 포팅하며, EL 5.14 백포트 라인 및 메인라인 기반 6.x 커널에 대해 커널 계열별 변형을 제공합니다. 이 버그는 사용자 공간 라이브러리 구성 요소가 없는 커널 전용 버그이므로 LibCare는 적용되지 않습니다.
2026년 7월 29일 기준 출시 현황.
KernelCare는 Januscape 역할 수정 사항과 이에 필요한 CVE-2026-46113 관련 수정 사항을 함께 제공하므로, 지원 여부는 CVE별로가 아니라 커널 계열별로 명시됩니다.
안정적이며, 완전히 홍보된
RHEL 10 – 패치 세트 K20260703_15
Oracle Linux 10 – K20260703_16
Rocky Linux 10 – K20260703_17
AlmaLinux 10 – K20260703_18
데비안 13 – K20260706_09
Ubuntu 22.04 – K20260706_01 (arm64용 _02, Azure용 _03, AWS용 _04)
Jammy HWE 커널을 적용한 Ubuntu 20.04 – K20260706_06 (Azure: _05, AWS: _07)
Ubuntu 24.04 – K20260707_01 (AWS: _02)
Proxmox VE 7 (5.15) – K20260706_08
Proxmox VE 8 (6.8) – K20260707_03
2026년 7월에 출시된 Enterprise Linux 9
RHEL 9 – K20260710_58
AlmaLinux 9 및 CloudLinux 9 – K20260710_60
Oracle Linux 9 – K20260710_63
Rocky Linux 9 – K20260710_65
단계적 도입
데비안 12 – K20260709_25
데비안 11 – K20260710_11
Ubuntu 20.04 표준 커널 – K20260710_10
CloudLinux 8 – K20260709_27
테스트 중
RHEL 8 – K20260710_31
AlmaLinux 8 – K20260710_41
Rocky Linux 8 – K20260710_43
CentOS 8 – K20260710_33
Oracle Linux 8 – K20260710_35
CloudLinux 7 하이브리드 – K20260710_39
아직 영업 중
Oracle UEK6, Oracle UEK7, Amazon Linux 2, Ubuntu 18.04.
Enterprise Linux 7도 이 문제의 영향을 받지만, 패치 일정은 잡혀 있지 않습니다. 실질적인 영향은 서비스 거부(DoS)에만 국한됩니다. 중첩된 VMX는 속도가 너무 느려 경합 조건이 발생하기 어렵기 때문에 테넌트에서 호스트로의 DoS 공격은 사실상 불가능하며, 로컬 권한 상승 경로는 CONFIG_BUG_ON_DATA_CORRUPTION에 의해 차단됩니다. EL7을 사용하는 호스트는 여전히 위에서 언급한 구성 상의 완화 조치를 적용해야 합니다.
RHEL 9, AlmaLinux 9, CloudLinux 9, Oracle Linux 9 및 Rocky Linux 9에 대한 Enterprise Linux 9 지원이 시작되었습니다. 이는 EL9가 저희 실험실에서 치명적인 호스트 패닉을 유발한 플랫폼이기 때문에 중요한 사항입니다. 따라서 취약점에 노출된 EL9 호스트는 여전히 가장 먼저 패치를 적용해야 하지만, 더 이상 패치가 나올 때까지 구성 상의 완화 조치에만 의존할 필요는 없습니다. 아직 지원 범위에 포함되지 않은 플랫폼은 Oracle UEK6 및 UEK7, Amazon Linux 2, Ubuntu 18.04이며, 해당 호스트는 여전히 앞서 언급한 완화 조치나 수정된 벤더 커널에 의존해야 합니다.
테스트 피드에서 신청하세요:
sudo kcarectl --update --prefix test
프로모션이 완료되면 프로덕션 피드에서 적용하세요:
sudo kcarectl --update
실행 중인 패치 빌드를 확인하십시오:
kcarectl --info | grep kpatch-build-time # build dated 2026-07 or later
Januscape에는 두 가지 수정 사항이 모두 필요하므로, 날짜만 믿고 넘어가지 말고 두 가지가 모두 포함되어 있는지 확인하십시오:
kcarectl --patch-info | grep -E
'CVE-2026-53359|CVE-2026-46113'
두 건이 일치하는 것이 명확한 답입니다. 앞서 언급한 라벨링 이력 때문에 CVE-2026-46113에 대한 일치 결과만으로는 역할별 수정 사항이 누락되었다는 증거가 될 수 없습니다. 이 경우, 설치된 K-tag를 위의 릴리스 목록이나 해당 커널 계열에 대한 KernelCare 적용 기록과 대조하여 확인해야 합니다. 빌드 날짜만으로는 아무것도 증명할 수 없습니다. 6월 중순 이후에 컴파일된 커널이라고 해서 이 수정 사항이 자동으로 포함된 것은 아니며, 두 가지 수정 사항이 모두 포함되어 있다는 보장도 없습니다. CVE 매핑, K-tag, 공급업체 정정 공지 또는 소스 코드를 직접 확인하십시오.
Januscape는 미미한 KVM 섀도 페이지 불일치를 게스트-호스트 경계의 오류로 전환합니다. 긴급 재부팅을 감당할 수 없는 가상화 클러스터의 경우, 재부팅이 필요 없는 패치를 통해 모든 노드를 중단시키거나 게스트 시스템을 중단시키지 않고도 실행 중인 커널 내에서 해당 경계를 봉합합니다.
참조
- Januscape (CVE-2026-53359), NVD – https://nvd.nist.gov/vuln/detail/CVE-2026-53359
- 공개 PoC 및 기술 문서, 김현우 (@v4bel) – https://github.com/V4bel/Januscape
- Januscape 수정 사항 업스트림 반영, 커밋 81ccda30b4e8 (메인라인, 2026년 6월) – https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=81ccda30b4e83d8f5cc4fd50503c44e3a33abfeb
- 관련 취약점 CVE-2026-46113 (“예기치 않은 GFN”), NVD – https://nvd.nist.gov/vuln/detail/CVE-2026-46113
- 관련 수정 사항, 커밋 0cb2af2ea66a – https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0cb2af2ea66ad8ff195c156ea690f11216285bdf
- 버그를 유발한 커밋 2032a93d66fa (2010-08-01)
- 동일 연구자가 발견한 크로스 아키텍처 취약점, “ITScape” KVM/arm64 탈출 – CVE-2026-46316
- Google kvmCTF – https://github.com/google/security-research/blob/master/kvmctf/rules.md