Why should I know this?

ARMv7 에서 Cacheflush를 사용할 때 주의점 본문

Knowledge/Android

ARMv7 에서 Cacheflush를 사용할 때 주의점

die4taoam 2020. 2. 22. 02:50

ARMv7 아키텍처에서 동적생성된 코드를 실행하거나 복호화 후 실행 시에 알 수 없는 이유로 SIGSEGV 나 SIGILL이 발생하는 경우가 있습니다. 빈도 또한 일정치 않고, 디버깅조차 어려우므로 이곳에 해결책을 기재해 공유하고자 합니다.

 

해결책은 Android의 다음 commit 을 참조하시면 됩니다.

git clone https://android.googlesource.com/platform/art

git show aeba572be73559c310de758dbcdac901e064ec07 

 

platform/art - Git at Google

 

android.googlesource.com

위의 코드에 대한 설명은 다음과 같습니다.

가상메모리가 물리메모리와 매핑되어 있지 않을때 Cacheflush는 실패합니다, 그리고 아무 작업도 하지 않고 실패했으므로 다시 Cacheflush를 하면, 물리메모리를 매핑해줄 이유가 전혀 없으므로 여전히 실패하게 될 겁니다. 그러므로 다시 가상메모리가 매핑되도록 강제하는 코드를 통해 이를 방지할 수 있습니다.

 

 

이와 같은 문제가 발생한 이유는 전적으로 ARM에 있습니다. ARMv7 아키텍처는 Cacheflush instruction을 특권명령으로 지정해놨는데, 덕분에 Cacheflush를 하기 위해서는 syscall을 해야 합니다. 문제는 커널에서 Cacheflush 의 완전 동작을 보장해주지 않으며, 덕분에 Cacheflush의 Fail을 프로그래머는 처리할 수 있어야 합니다. 문제는 해당 로직이 구형 커널에서는 커널 개발자들 조차 우왕좌왕하며 제대로 처리를 하지 못하므로 기본적으로 커널을 믿고 개발하는 선량한 개발자들의 머리카락만 뽑히는 결과를 낳고 말았습니다.

 

가장 심각한 3.0.X 대역 커널에서는 심지어 Cacheflush는 결과 값을 반환조차 하지 않습니다.딥빡

 

 

 

Comments