Pointer authentication code

Ahn9807 (토론 | 기여)님의 2024년 9월 4일 (수) 03:06 판
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)


개요

Pointer Authentication Code (PAC)는 ARMv8.3 (AArch64)에서 도입된 보안 기법으로, 포인터를 사용하기 전에 이를 인증하기 위해 사용된다. ARM PAC은 Cherry비슷한 Capability-based isolation환경을 Application과 Kernel모두에게 제공한다.

PAC

Return oriented programming과 같은 공격을 방어하기 위해서, Pointer address의 무결성(Integrity)를 체크하는 하드웨어적인 SFI방식을 제공한다. 이를 통해서 포인터가 사용되기 전에 무결성을 체크하기 때문에, 포인터를 안전하게 사용할 수 있게 된다. 콘텍스트에는 base pointer address와 같은 것들이 사용된다.

하드웨어는 64bit에서 사용되지 않았던 top bit들에 pointer가 생성될 당시 사용된 Context와 임의의 key를 통해서 생성된 Message autentication code를 저장한다. 포인터에 접근할때, key와 context가 다르면 포인터에 대한 접근이 fault를 발생시키기 때문에 안전하게 ROP, Spatial, Temporal과 같은 Heap memory bug들을 예방할 수 있다.

PAC Instruction

<function prologue>
  paciasp			; sign (lr=x30)
  stp fp, lr, [sp, #0]		; store lr
<function body>
<function epilogue>
  ldp fp, lr, [sp, #0]		; load lr
  autiasp			; authentication
  ret				; ret

PAC은 사용하기 위해선 반드시 Assembler혹은 Compiler의 도움을 받아야 한다. 즉, Transparent한 솔루션이 아니다.

  • PAC_A_B: B레지스터의 Pointer autentication code를 A키를 이용하여서 만들어내는 어셈블러이다. e.g., PACIASP는 IA (Instruction key)로 SP레지스터를 암호화. 키에 대한 자세한 설명은 메뉴얼을 참고.
  • AUT_A x: 키 A를 사용하여서, x레지스터에 대한 Athentication을 체크한다. 만약 틀릴경우에는 fault가 발생한다.
  • 그외에 load, store에 사용되는 명령어가 따로 있다.

장점

  • 하드웨어의 가속을 이용하여서 SFI를 효율적으로 강력하게 사용할 수 있음

단점

  • 추가적인 Compiler의 도움을 받아야 함
  • Performance critical한 컴포넌트에 적용시키기에는 still, overhead를 무시할 수 없음. e.g., SPEC CPU 2006에서 sjeng벤치마크의 결과가 대략 3배 정도로 뛰기도 함. NaCL과 같은 Software-based isolation기법보다 느림. 이는 하드웨어가 빠르더라도, 컴파일러 기반의 체크 로직 추가가 어떤 오버헤드를 가져올 수 있는지를 모여주는 예시임.
  • PAC을 우회할 수 있는 취약점들이 존재함

참고

  1. Limitations and Opportunities of Modern Hardware Isolation Mechanisms (Usenix ATC'24)
  2. https://velog.io/@pensieveview/Pointer-authentication