Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Apple Silicon HVF
Search
Mach0xFF
July 10, 2021
0
750
Apple Silicon HVF
Kernel/VM Online Part3 LT
Mach0xFF
July 10, 2021
Tweet
Share
More Decks by Mach0xFF
See All by Mach0xFF
Hypervisor.framework(HVF)の中身
mach0xff
2
1.5k
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
33
2.9k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
131
33k
Automating Front-end Workflow
addyosmani
1366
200k
Imperfection Machines: The Place of Print at Facebook
scottboms
264
13k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Raft: Consensus for Rubyists
vanstee
136
6.6k
Docker and Python
trallard
40
3.1k
Bash Introduction
62gerente
608
210k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
Git: the NoSQL Database
bkeepers
PRO
427
64k
VelocityConf: Rendering Performance Case Studies
addyosmani
325
24k
Testing 201, or: Great Expectations
jmmastey
38
7.1k
Transcript
Apple Silicon HVF K/VM Online Part3
% whoami - M6Mです(Mach0xFFです) - 前回も似たようなテーマだった - ごめんなさい
作ろうとしたもの - keystone engineとHVFを組み合わせたA64アセンブリ(ARM64)のREPL - 先に言うとREPLはできていません - Linux用にptraceベースな既存のものが存在する - https://github.com/yrp604/rappel
- A64命令、少し複雑なものが多々ある(UBFX, BICS, FJCVTZS) - 必要に応じて命令を実行してくれるツールがあったらいいなあ - アセンブリ書いたファイル読み込ませてレジスタダンプするところまではできた
← x2 = x0 & ~x1
ここからは - ここからはHVFの実装について調査した結果を書きます - REPLもどきは一度忘れてください
Apple A14/M1チップ - μArchは基本同じ - Firestorm (big/p-core) / Icestorm (LITTLE/e-core)
- A14 for iOS devices、M1 for macOS/iPadOS devices - A14/M1チップ上ではEL2によるXNU(カーネル)の動作モードが存在する - これは以下のことからわかる - XNUで(実質的に)最初に実行される関数 start_first_cpuで、HCR_EL2レジスタに E2H (EL2 Host, bit 34)が設定される - その裏付けとして、EL2動作時に*_EL1システムレジスタに( re-routeされずに)アクセスするための *_EL12レジスタが実装され、読み書き( MRS/MSR)されている - Hypervisorが実装されている以上、どこかしらで EL2による動作が必要
hv_vm_create
hv_trap - X16レジスタに(-5)を入れてSVC - カーネルではどうなるか
- SVC命令によるExc発生→Synchronous exception from Lower EL using AArch64 - ESR_EL1(Exception
Syndrome Register EL1)の値からExcの要因を取得 - EL2で動作している場合、ESR_EL2にre-routingされる(はず) - SVC命令によるものだとKernelが判定→handle_svc()関数へ - UserがX16に入れたSyscall numberをint trap_noとして取得 - 基本的に正ならUnix、負ならMach - 例外として (osfmk/mach/arm/traps.h) - MACH_ARM_TRAP_ABSTIME (-3) - MACH_ARM_TRAP_CONTTIME (-4) - xnuのソースコードにはここまでしか書かれていないが…
- macOS 11.3のカーネル、handle_svc()に該当するDisassembly - CMN (CoMpare Negative)命令によりtrap_noを(-5)と比較 - この部分はまだオープンになっていない
Entitlements - ところでApple Silicon HVFを使うには実行ファイルを署名した上で、必要な Entitlementsを付与する必要がある - Entitlements: 実行ファイルが「何か権限の必要なこと」を行う際に必要となる、Plist形式のデータ -
PlistはとりあえずXMLと考えて構わない - XNUが認識するVM作成に関するEntitlementsは以下の3つ - (1) com.apple.security.hypervisor - (2) com.apple.private.hypervisor.vmapple - (3) com.apple.private.hypervisor - 公式には(1)のみ存在することになっている( VM作成ならこれで事足りる) - https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_hypervisor - カーネル内部では(2)・(3)のEntitlementsの有無も確認する - 許可される最大のISAのレベルが変化する - HVF経由だと(1)しか作れない(hv_vm_create()に適切な引数を渡す必要あり) - ただしcom.apple.privateで始まるため、通常起動時はこの権限を付与したバイナリは実行を拒否される - 具体的には、amfidというデーモンにSIGKILLされる
迂回路 (boot-args) - 迂回路はある - boot-argsに “amfi_get_out_of_my_way=1” を設定 - %
sudo nvram boot-args=... - これやるとセキュリティ的によろしくない状態になる - ソフトウェアやドライバが動かなくなることもしばしば - 実験が終わったら元に戻しましょう - こうするとamfidによるチェックが行われなくなるため、先述の(2)•(3)の Entitlementsを付与可能 - (1)•(2)•(3)は具体的にどう違うのか?
Hidden HVF API - _hv_capability(uint64_t cap, uint64_t *out) - 引数名は適当
- Hypervisor.frameworkのヘッダファイルに存在しない API - 共有ライブラリにシンボルとして存在する - 内部ではX0レジスタに#0を設定した上でSVCをする - 先程の3種のEntitlementsをそれぞれ設定して呼び出してみる
None
None
HACR_EL2 - control_hacr だけ異なっている - hacr → Hypervisor Auxiliary Control
Register - 64-bitレジスタ、内容はIMPLEMENTATION DEFINED - すなわちコア実装による - (2)•(3)ではbit 0がセットされている - このビットに何か秘密がある? - カーネルを読んでみたが、まだ詳細は不明 …
vmapple - ...vmappleのEntitlementを付与するとAppleのIMPLEMENTATION DEFINEDなシステム レジスタが使える…? - https://blog.svenpeter.dev/posts/m1_sprr_gxf/#open-questions - https://twitter.com/never_released/status/1390394188395597831 -
システムレジスタの値を取得するには - hv_vcpu_get_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t reg, uint64_t *value) - ただし、ヘッダファイルには reg (uint16_t) としてIMPLEMENTATION DEFINEDレジスタはない - 各種Entitlementsを付与しても、エラー発生せずに取得できるシステムレジスタに変化はなかった - 内部で呼ばれるSyscallを使って取得できる? - 該当Syscallの引数が固定されている - カーネル内部の構造体に、r/wが許可されるsysregを設定するフィールドがあるっぽい - (時間切れ)
- まとまりのない話になってしまった - 将来的に(privateが外れて)vmappleのEntitlementが解放されたら嬉しい - Apple Silicon VMWareとかParallelsはこのEntitlementを使って開発されてそう - 調査継続します(REPLも作りたい)