NX 비트는 보안만을 위한 것이 아니다

1 hour ago 2

ARM64 베어메탈 하이퍼바이저에서 CTR_EL0 인터셉트를 켤 때 기기가 멈춘 원인은 분기 예측에 따른 추측적 명령어 인출이 실행 가능하게 매핑된 MMIO 영역에 접근했기 때문이었음 직접 호출인 bl은 작동하고 간접 호출인 blr은 실패했으며, Cortex-A53이 분기 대상을 잘못 예측해 0x0의 잠긴 bootrom에서 명령어를 가져온 것으로 좁혀짐 ARM에서 메모리를 Device로 지정하면 추측적 데이터 접근만 차단되며, 추측적 명령어 접근까지 막으려면 해당 영역을 비실행으로 표시해야 함 MMIO 페이지에 NX 비트를 적용하자 커널 패치 없이 반년 만에 Android가 완전히 부팅됐고, ARM 공식 문서에서도 모든 추측적 접근을 막으려면 Device와 비실행 속성이 모두 필요하다고 명시함 DEP를 단순한 스택 오버플로 방어책으로만 보면 이런 하드웨어 오류를 놓칠 수 있으며, ARM의 실행 권한은 메모리 접근 동작을 결정하는 기능적 속성이기도 함 CTR_EL0 인터셉트에서 시작된 멈춤 현상 postmarketOS용 ARM64 베어메탈 하이퍼바이저에서 CTR_EL0 인터셉트를 켜면 전화기가 무작위로 멈추고 몇 초 뒤 watchdog이 시스템을 재시작했음 이 인터셉트는 하이퍼바이저의 핵심 목적이어서 생략할 수 없었음 watchdog을 비활성화해도 부팅되지 않아 단순한 부팅 지연은 아니었음 AArch64의 특수 기능 레지스터(SFR)는 MRS와 MSR로 범용 레지스터와 데이터를 주고받으며, 나머지 레지스터는 그대로 유지해야 함 처음에는 예외 처리기가 보존 대상 레지스터를 손상하거나 결과 레지스터를 갱신하지 못한다고 의심했음 트램펄린과 스택 할당을 검토하고 QEMU에서 전체 처리기를 한 단계씩 실행했지만 예상대로 동작함 실제 하드웨어에서는 의도한 출력 레지스터를 포함해 어떤 레지스터도 변경되지 않았음 첫 번째 버그: 명령어·데이터 캐시 비일관성 실행 가능한 기계어가 담긴 msr_accessors 배열을 런타임에 정렬한 것이 첫 번째 문제였음 ARM은 I-cache와 D-cache가 자동으로 일관성을 유지하지 않기 때문에 데이터 변경이 아직 RAM에 반영되지 않거나 명령어 캐시에 이전 코드가 남을 수 있음 정렬을 빌드 단계로 옮기자 실제 하드웨어에서도 처리기가 올바르게 동작했지만, 시스템은 여전히 부팅되지 않았음 예외와 커널 충돌 추적 ARM 구현은 공급업체가 참조 아키텍처를 수정하거나 자체 구현할 수 있어, 다음으...

Read Entire Article