풀이 날짜: 2026-09-14 (사용자 확정). 익스플로잇 성공은 2026-09-16 사용자 확인에 따른다. 아래 실행 결과는 보존된 원본 기록이며 이번 감사에서 새로 실행한 결과가 아니다.

가상 머신 주소 변환의 경계 오류

ainique는 커널 안에서 구현한 가상 CPU의 메모리 변환을 다룬다. 실제 분석 대상은 deploy/prob.c의 페이지 테이블과 배포 Linux 6.13.7 환경이다. 단순히 '커널 메모리 오류'라고 부르기보다, 게스트 주소에서 계산한 인덱스가 호스트의 포인터 배열에 직접 사용된다는 경계를 짚어야 한다.

핵심 코드와 불변조건

아래는 qcpu_get_pte_from_va_failsafe에서 각 계층의 인덱스를 계산하는 부분을 발췌한 것이다. 중간 NULL 검사와 나머지 처리는 생략했다.

qcpu_pte_t ***pml4e = qcpu_get_pml4e(cr3, va >> 39);
qcpu_pte_t **pdpe = qcpu_get_pdpe(pml4e, (va >> 30) & 0x1ff);
qcpu_pte_t *pde = qcpu_get_pde(pdpe, (va >> 21) & 0x1ff);
qcpu_pte_t pte = qcpu_get_pte(pde, (va >> 12) & 0x1ff);

하위 세 계층은 9비트 범위로 제한하지만 최상위 계층은 상위 비트가 그대로 남는다. qcpu_get_pml4e는 범위를 검사하지 않고 cr3[pml4e_index]를 반환한다. 할당한 root는 4 KiB 포인터 테이블이므로, NULL 여부를 검사하기 전에 배열 접근 자체가 유효해야 한다. 함수 이름의 failsafe와 달리 NULL 검사만으로 이 계약을 보장할 수 없다.

qcpu_alloc_pageqcpu_free_page도 같은 최상위 인덱스 계산을 사용한다. FINAL_REPORT는 범위를 벗어나 읽은 값을 하위 테이블 포인터로 신뢰하는 점을 핵심 영향으로 정리한다. 정상적인 게스트 페이지 접근이 커널 메모리의 소유권 경계를 침범할 수 있다는 것이 root cause와 메모리 primitive 사이의 연결이다.

가설을 좁힌 과정

최종 보고서는 Candidate A만 완성한 것으로 구분한다. 고정된 객체 생성 횟수만으로 메모리 배치가 결정된다는 초기 가정은 실제 할당 관찰과 맞지 않아 폐기했다. 또한 RAM 용량 전체를 접근 가능한 물리 영역으로 취급한 실험은 실패했고, 메모리 지도에서 사용 가능한 영역을 구분하도록 정정한 이력이 있다. 이 둘은 취약점의 존재 자체와 별개로 당시 구현이 의존한 환경 가정을 검토한 기록이다.

최종 구현에는 내부 상태가 예상과 일치하는지 확인하는 검사와 결과 read-back이 있다. 보고서의 자기 데이터 읽기 표식은 메모리 읽기 성질의 증거이고, 사용자 공간으로 돌아온 뒤의 UID 확인은 권한 결과의 증거다. 한 표식을 전체 성공의 대체물로 취급하지 않는다.

결과와 검증 범위

2026-09-16 사용자 확인은 익스플로잇 성공이다. experiments/e2e_clean_1.log부터 세 clean-run 로그에는 로컬 UID 0과 flag 장치 읽기 성공이 기록되어 있다. 제공 커널·rootfs, 64 MiB RAM 및 KASLR·SMEP·SMAP·KPTI와 panic 설정을 유지한 환경의 결과다. 게스트 네트워크는 비활성화되어 있었으며 공식 원격 검증 근거는 없다.

이번 감사는 소스와 기존 보고서를 대조한 것이다. 커널 이미지·바이너리·solver를 실행하지 않았다. 파일의 대용량 여부와 관계없이 원본 rootfs와 분석 자료는 staging에 보존한다.

근거 자료

  • sources/ainique/deploy/prob.c
  • sources/ainique/experiments/FINAL_REPORT.md
  • sources/ainique/GATES.md

원본 문서·solver·검증 로그는 전달 staging에 보존되어 있다. 이 경로들은 provenance이며 CMS의 다운로드 첨부 링크가 아니다.