Pointer authentication code (PAC)

Ph.D Chroniclesยท2021๋…„ 8์›” 17์ผ
0

ARM

๋ชฉ๋ก ๋ณด๊ธฐ
1/4

๐Ÿ“ Pointer authentication?

ARMv8.3 (AArch64) ์—์„œ ์ถ”๊ฐ€๋œ ๋ณด์•ˆ๊ธฐ๋ฒ•์œผ๋กœ, Pointer๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „ ์ธ์ฆํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชฉ์ ์œผ๋กœ ๋„์ž…๋˜์—ˆ๊ณ , Pointer authentication code (PAC) ๋˜๋Š” Pointer authentication (PAuth) ๋ผ๊ณ ๋„ ๋ถˆ๋ฆฌ๊ณ  ์žˆ๋‹ค.

Background

Function call/return ์‹œ์— ์ƒ์„ฑ๋˜๋Š” ret instruction์„ ์ด์šฉํ•œ Return oriented programming (ROP) ๊ณต๊ฒฉ์ด ์žˆ๋‹ค. ๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด ret์œผ๋กœ ์—ฐ๊ฒฐ๋˜๋Š” ๋ช…๋ น์–ด๋ฅผ ๋ฐ˜๋ณต chaining ํ•˜๋ฉด์„œ ๊ณต๊ฒฉ์ž๊ฐ€ ์›ํ•˜๋Š” ๋Œ€๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ, ํ”„๋กœ๊ทธ๋žจ์˜ call flow๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ์ทจ์•ฝ์ ์ด๋‹ค. Jump oriented programming (JOP)๋„ ๊ฐ™์€ ๋ฐฉ์‹์ด๊ณ , ๋‹จ์ง€ br ๋“ฑ instruction์„ ์ด์šฉํ•  ๋ฟ์ด๋‹ค.

PAC๋Š” ์ด๋ฅผ ๋ฐฉ์–ดํ•˜๊ณ ์ž pointer address์˜ ๋ฌด๊ฒฐ์„ฑ (integrity)์„ ์ฒดํฌ ํ•ด์„œ, ์•„๋ฌด๋ฐ๋กœ๋‚˜ call flow๋ฅผ ๋ณ€๊ฒฝ ํ•  ์ˆ˜ ์—†๊ณ , ํ”„๋กœ๊ทธ๋ž˜๋จธ์— ์˜ํ•ด ์˜๋„๋˜์–ด ์žˆ๋Š” ๊ณณ์œผ๋กœ๋งŒ return/branch ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ฐ•์ œํ•˜๊ฒ ๋‹ค๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

In a nutshell

pointer address์— Keyed message authentication code (MAC)์„ ๋„ฃ์ž!
๊ทธ๋ฆฌ๊ณ  Keyed MAC (์ธ์ฆ์ฝ”๋“œ)๊ฐ€ ๋งž์„ ๊ฒฝ์šฐ์—๋งŒ pointer address๋ฅผ ์‚ฌ์šฉํ•˜์ž!

๊ทธ๋ฆผ์œผ๋กœ ๋ณด์ž๋ฉด, ๋ชจ๋“  pointer ๋งˆ๋‹ค ์•„๋ž˜์™€ ๊ฐ™์€ ์ธ์ฆ์ฝ”๋“œ๊ฐ€ ๋ถ™์–ด์žˆ๋Š” ์…ˆ์ด๋‹ค.

PAC๋Š” 64bit ์ฃผ์†Œ์ฒด๊ณ„์—์„œ ๋™์ž‘ํ•˜๋Š”๋ฐ, 64bit์—์„œ๋Š” pointer ํ‘œํ˜„์— ์žˆ์–ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” top byte๋ฅผ ์ด์šฉํ•˜๊ณ  ์žˆ๋‹ค. (MMU ๊ตฌํ˜„์— ๋”ฐ๋ผ byte ์ˆ˜๋Š” ๋‹ค๋ฆ„)

๊ทธ๋ฆผ์—์„œ ์—ด์‡ ๋ชจ์–‘์ด ์ธ์ฆ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” Key ์—ญํ• ์„ ํ•˜๋Š”๋ฐ, Key๋Š” pointer type๊ณผ privileged level์— ๋”ฐ๋ผ ์ด 5๊ฐ€์ง€ key๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.

  • APIAKey, APIBKey โ†’ Instruction key
  • APDAKey, APDBkey โ†’ Data key
  • APGAKey โ†’ Generic key

A key๋Š” user mode, B key๋Š” kernel mode์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.
๊ทธ๋ฆผ์—์„œ context/tweak์€ Keyed MAC์˜ input์œผ๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ, output์˜ entropy๋ฅผ ์ค€๋‹ค. (๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ PAC ๊ฐ’์„ ์˜ˆ์ธกํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ ๋‹ค๋Š” ๋œป)

PAC๋ฅผ ๋งŒ๋“œ๋Š” ์‹œ์ ์— ์‚ฌ์šฉ๋˜์—ˆ๋˜ key์™€ context/tweak์„ ์ด์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น pointer address๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ๊ณต๊ฒฉ์ž์— ์˜ํ•ด call flow๊ฐ€ ๋‹ค๋ฅธ ์ง€์ ์—์„œ ์˜ค๊ฒŒ ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š” key๋‚˜ context/tweak์ด ๋งž์ง€ ์•Š๊ฒŒ ๋˜๋ฏ€๋กœ ํ•ด๋‹น return/branch๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ.

๐Ÿ“ PAC instruction

PAC๊ฐ€ ์ถ”๊ฐ€๋œ ๋ช…๋ น์–ด instruction์€ ์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ์ด๋‹ค.
ํ”ํžˆ ๋ณด์ด๋Š” function prologue, body, epilogue์— pacisp, autiasp๊ฐ€ ์ถ”๊ฐ€๋œ ํ˜•ํƒœ.
(<, >๋Š” assembler์—์„œ๋Š” ์—†๋Š” ํ‘œํ˜„์ด์ง€๋งŒ, ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ์ถ”๊ฐ€ํ•˜์˜€๋‹ค)

<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

ํฌ๊ฒŒ Sign/Authentication ๋™์ž‘์œผ๋กœ ๊ตฌ๋ถ„๋˜๋ฉฐ, Sign์€ pointer์— PAC๋ฅผ ๋ถ™์ด๋Š” ๊ณผ์ •, Authentication์€ pointer ์‚ฌ์šฉ ์‹œ์— PAC๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๊ณผ์ •์ด๋‹ค.

PAC* : pointer authentication code generation

PAC๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ณ„์—ด์˜ instruction์€, keyed MAC์„ ์‚ฝ์ž…ํ•˜๋Š” ์šฉ๋„์ด๋‹ค.
๊ณ„์‚ฐ์„ ํ•œ ๋’ค ๊ฒฐ๊ณผ๊ฐ’์€ target pointer address์˜ top byte์— ์œ„์น˜์‹œํ‚ค๊ฒŒ ๋œ๋‹ค.

PACIASP : Instruction key A๋กœ lr์˜ PAC ๊ณ„์‚ฐ (context = sp, stack pointer)
PACIA x8, x9 : Instruction key A๋กœ x8์˜ PAC ๊ณ„์‚ฐ (context = x9)
PACIAZ x8 : Instruction key A๋กœ x8์˜ PAC ๊ณ„์‚ฐ (context = 0)

AUT*: pointer authentication code verification

AUT๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ณ„์—ด์˜ instruction์€, pointer address์— ๋ถ™์–ด์žˆ๋Š” keyed MAC์„ ๊ฒ€์ฆํ•˜๋Š” ์šฉ๋„์ด๋‹ค. ๊ฒ€์ฆ์ด ๋งž์„ ์‹œ์—๋Š” PAC๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  pointer๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๊ณ , ๊ฒ€์ฆ์ด ํ‹€๋ฆด ์‹œ์—๋Š” fault (SError)๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.

AUTIA x8, x9 : Instruction key A๋กœ x8์˜ PAC ๊ณ„์‚ฐ, valid pointer๋Š” ๋‹ค์‹œ x8์— ์œ„์น˜

BLR, RET

๊ทธ ์™ธ ์ถ”๊ฐ€๋˜๋Š” instruction์€ AUT๊ณ„์—ด์— load๋‚˜ return๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•œ ๊ฒƒ.

BLRAA x8, x9 : authenticate-and-branch๋กœ x8์˜ PAC ๊ฒ€์ฆ ํ›„ branch
LDRA* : authentication-and-load
RETA* : authentication-and-return, LR์˜ PAC ๊ฒ€์ฆ (context = sp) ํ›„ ret

๐Ÿ“ PAC in your code

์ด๋ก ํŽธ์„ ๊ทธ๋Ÿญ์ €๋Ÿญ ์ดํ•ดํ–ˆ์œผ๋‹ˆ, ๊ฐ ์‹ค์ „ ์ ์šฉ์„ ํ†ตํ•ด ์‹ค์ œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด์•˜๋‹ค

Kernel engineer

์ปค๋„๊ฐœ๋ฐœ์ž๋ผ๋ฉด, upstream์— ์˜ฌ๋ผ์™€ ์žˆ๋Š” PAC ๊ด€๋ จ config๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค.

CONFIG_ARM64_PTR_AUTH

์ปค๋„์—์„œ exec ์‹œ์ ์— user application ๋งˆ๋‹ค A key๋ฅผ ํ• ๋‹นํ•˜๊ฒŒ ๋˜๊ณ , scheduling ๋  ๋•Œ๋งˆ๋‹ค key๋Š” user context๋กœ ์˜ ์ผ๋ถ€๋กœ save/restore ํ•ด ์ฃผ๊ฒŒ ๋œ๋‹ค.
upstream patch: https://lore.kernel.org/lkml/20180503132031.25705-1-mark.rutland@arm.com/

Application engineer

๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ pac, aut ์ฝ”๋“œ๋ฅผ assembly์— ์ฝ”๋”ฉํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ,
๋ณดํ†ต์€ ์ง์ ‘ ์ฝ”๋”ฉ๋ณด๋‹ค๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋„์›€์„ ๋ฐ›์•„์•ผ ํ•œ๋‹ค.

gcc ํ˜น์€ armclang์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ปดํŒŒ์ผ ์˜ต์…˜์œผ๋กœ PAC๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค.

-mbranch-protection=pac-ret+leaf+b-key

branch-protection์ด๋ผ๋Š” ๋ผ๋ฒจ์ด ํ•˜๋‚˜ ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฉฐ, ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์€
standard: ๋ชจ๋“  ์˜ต์…˜ ํฌํ•จ
pac-ret: PAC๋ฅผ ์œ„ํ•œ default ์˜ต์…˜
leaf: function call stack์˜ leaf ๋…ธ๋“œ๊นŒ์ง€ PAC๋ฅผ ์ ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์˜ต์…˜
b-key: b-key ์‚ฌ์šฉ ์˜ต์…˜

Android

android-ndk-r23-beta3 toolchain์—์„œ PAC๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค.
android-ndk-r23-beta23/toolchains/llvm/prebuilt/linux-x86_64/bin/

$ aarch64-linux-android31-clang --version
Android (7211189, based on r416183) clang version 12.0.4

clang 12.0.x ์ด์ƒ ๋ฒ„์ „์ž„์ด ํ™•์ธ๋˜๋ฉด, ์•„๋ž˜ ์ปดํŒŒ์ผ ๋ช…๋ น์„ ํ†ตํ•ด PAC๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

$ aarch64-linux-android31-clang -o test test.c -mbranch-protection=pac-ret+leaf

iOS

Xcode์—์„œ arm64e ๋นŒ๋“œ๋ฅผ ํ†ตํ•ด PAC๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค.
๊ฐ€์ด๋“œ๋Š” ์—ฌ๊ธฐ์— ์žˆ๊ณ , ptrauth.h๋ฅผ ๋ณด์‹œ๋ฉด PAC key๋‚˜ ๊ฐ์ข… PAC function๋“ค์˜ ์ •์˜๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค.

PAC-ed binary

์œ„ ์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์„ ์ ์šฉํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ์˜ assembler๋ฅผ ๋œฏ์–ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋˜์–ด ์žˆ๋‹ค.

$ llvm-objdump
0000000000001770 <main>:
    1770: 3f 23 03 d5   hint    #25
    1774: ff 83 00 d1   sub     sp, sp, #32
    1778: fd 7b 01 a9   stp     x29, x30, [sp, #16]
    177c: fd 43 00 91   add     x29, sp, #16
...
    17a8: fd 7b 41 a9   ldp     x29, x30, [sp, #16]
    17ac: ff 83 00 91   add     sp, sp, #32
    17b0: bf 23 03 d5   hint    #29
    17b4: c0 03 5f d6   ret

hint #25 ์™€ hint #29๋ผ๋Š” ๋ช…๋ น์–ด๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ์žˆ๋‹ค!
ํ•ด๋‹น ๋ช…๋ น์–ด๋Š” ARM architecture reference ์—์„œ ๋‚˜์˜ค๋Š” opcode ํ†ตํ•ด์„œ ํ•ด์„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, hint #25๋Š” pacisp์— ํ•ด๋‹น๋œ๋‹ค. hint #29๋Š” authisp๊ฐ€ ๋œ๋‹ค.

์ผ๋ฐ˜์ ์ธ objdump๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋ฐœ์ž๋ผ๋ฉด, pac๋‚˜ aut instruction์ด ๋ณด์ด์ง€ ์•Š์„ํ…๋ฐ,
๊ทธ ์ด์œ ๋Š” objdump์—์„œ opcode ๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ์‹์—์„œ ์•„์ง PAC๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ
๊ฐ•์ œ๋กœ binutil์„ ์—…๋ฐ์ดํŠธ ํ•˜๊ฑฐ๋‚˜, llvm ์žฌ๋นŒ๋“œ๋ฅผ ํ•œ๋‹ค๋ฉด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“ Discussion

๋Œ€๋ถ€๋ถ„์˜ ROP/JOP ์ทจ์•ฝ์ ์€ PAC๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•œ ๊ฒƒ ๊ฐ™๋‹ค.
๊ทธ ๋™์•ˆ ROP/JOP ๋ฐฉ์–ด๊ธฐ๋ฒ•์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ๋Š” (=๋ฌด๋ ฅํ•˜๊ฒŒ๋Š”) ASLR๋ถ€ํ„ฐ code signing, shadow stack, CFI๊นŒ์ง€ ๋งŽ์€ ๊ธฐ๋ฒ•๋“ค์ด ์†Œ๊ฐœ๋˜์—ˆ๋Š”๋ฐ PAC๋Š” ํ•˜๋“œ์›จ์–ด ์ ์œผ๋กœ ์„ฑ๋Šฅ๋ฌธ์ œ๋ฅผ ์ตœ์†Œํ™” ํ•ด์„œ ROP/JOP๋ฅผ ์ƒ๋‹นํžˆ ๋งŽ์€ ๋ถ€๋ถ„ ๋ฐฉ์–ดํ•˜๊ฒŒ ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.

๋‹ค๋งŒ, ๋Š˜ ๊ทธ๋ ‡๋“ฏ PAC๋ฅผ ๋‹ค์‹œ ์šฐํšŒํ•˜๋Š” ์ทจ์•ฝ์ ๋“ค์ด ๋‚˜์˜ค๊ณ  ์žˆ๋Š”๋ฐ ๋‹ค์Œ ํŽธ์— ์ด์–ด์„œ-.

profile
Security researcher, Ravenclaw wannabe

0๊ฐœ์˜ ๋Œ“๊ธ€