x86におけるメモリアクセス権のルール
定期的に忘れる気がするのでメモ.SDM Volume 3A 4.1.3, 4.6参照.
用語
- supervisor mode access
- CPL < 3 でのアクセス
- user mode access
- CPL == 3 でのアクセス
- supervisor mode address
- page entryのU/S bitが一つでも0である領域*1
- user mode addres
- supervisor mode address以外の領域
- implicit supervisor-mode access
- 命令経由でのシステムのデータ構造(GDTなど)へのアクセス
- explicit supervisor-mode access
CPUの機能
- SMEP (CR4 bit 20)
- supervisor modeの場合user mode addressで実行不可
- SMAP (CR4 bit 21)
- supervisor modeの場合user mode addressへのwrite不可
- PKE (CR4 bit 22)
- Protection Keyを有効化
- WP bit (CR0 bit 16)
- 書き込み保護
- NXE (IA32_EFER SMR bit 11)
- 実行権限
- U/S bit (page table)
- user / supervisor modeの決定
- R/W bit (page table)
- 読み書き権限
備考
- 操作を完了するには,条件1と条件2の2つを満たす必要がある
- 条件1はsupervisor modeがuser mode addressにアクセスするための条件
- 条件2は実行条件
- 条件が複数ある場合はどちらかが満たされば良い
- supervisor modeでuser modeへwriteする場合,2x2=4通りの条件の組み合わせがある
- 空欄は無条件を意味する
- R/W == 1 というのはページテーブルの各段でR/Wが1ということ
- ぱっとみややこしいが,以下のような規則に基づいていることが分かる
- user modeからsupervisor mode addressはアクセス不可
- 書き込み制限 (WP = 1) は R/W=1 で回避可能
- user領域へのアクセス制限 (SMAP=1) はEFLAGS.AC=1にすることで回避可能
- このためにACフラグをセット/リセットするSTAC/CLAC命令がある
- 実行不可能 (NXE=1) はXD=0で回避可能
- アクセス権限がない場合
#PF
例外が発生 - 32bit pagingの場合,NXE bitの機能はない
- user mode addressへのread/writeは別途Protection Keyの制約がかかる
- SMEPは2012年ごろ(ivy bridge),SMAPは2014年ごろ (broadwell), Protection Keyは2015年ごろ(skylake)から導入
- 確認は /proc/cpuinfo で smap, smep, pku
Protection Key
- CR4.PKE = 1 のとき,paging-structure entryの62:59の4bitをprotection keyとして使う
- PKRUレジスタにprotection keyでアクセスし,アクセス権があるかを確かめる
- PKRU[2i] (0 <= i <= 15) : access-disable
- NOTE: executionはできる
- PKRU[2i+1] (0 <= i <= 15) : write-disable
- supervisor modeの場合,WP=0ならprotection keyの結果は無視される
- PKRU[2i] (0 <= i <= 15) : access-disable
- protection keyはsupervisor mode addressに関しては無視される
*1:PML4E,PDPTE,PDE,PTEいずれかでU/S bitが0という意味