SIPをもっと深く知ってみよう！　〜SIPは一体何を保護しているのか〜


## きっかけ
先日El CapitanにアップデートしたところXtraFinderが動かなくなり、
最終的に、リカバリーモードで 

```
csrutil enable --without debug
```
として一部のSIPの機能を解除することで解決しました。

盲目的にセキュリティを甘くしてしまいましたが、このままだと気持ち悪いのでいろいろと調べてみました。

## csrutilとは
csrutilはSIPの機能を有効/無効にするためのコマンドです。
これは通常時に実行しても

```
csrutil: failed to modify system integrity configuration. This tool needs to be executed from the Recovery OS.
```
と表示され、リカバリーモード時しか実行できないようになっています。
またオプションを付けることで、一部機能のみ有効/無効とする設定も可能です。

### 有効/無効な制限の確認
csrutilにはstatusコマンドが存在し、デフォルトでは
```System Integrity Protection status: enabled.```
と表示されます。

一方、一部機能を無効にした場合以下のような表記になります。

```
System Integrity Protection status: enabled (Custom Configuration).

Configuration:
	Apple Internal: disabled
	Kext Signing: enabled
	Filesystem Protections: enabled
	Debugging Restrictions: disabled
	DTrace Restrictions: enabled
	NVRAM Protections: enabled
```

どうやらSIPで管理される制限はこれらのようです。	

## さらに具体的に
ここまでで大体の制限はわかりましたが、さらに具体的に見ていきます。
調べてみたところ、これらの設定はcsr-active-configという値を参照しているということがわかりました。

この値は

```
nvram -p 
```
を実行することで確認できます。

上記の設定の場合
```csr-active-config	%14%00%00%00```
という値になり、これは0x14を表しているようです。

ここで、Appleが公開しているソースコードによると

```cpp
/* Rootless configuration flags */
#define CSR_ALLOW_UNTRUSTED_KEXTS	(1 << 0)
#define CSR_ALLOW_UNRESTRICTED_FS	(1 << 1)
#define CSR_ALLOW_TASK_FOR_PID		(1 << 2)
#define CSR_ALLOW_KERNEL_DEBUGGER	(1 << 3)
#define CSR_ALLOW_APPLE_INTERNAL	(1 << 4)
#define CSR_ALLOW_UNRESTRICTED_DTRACE	(1 << 5)
#define CSR_ALLOW_UNRESTRICTED_NVRAM	(1 << 6)
#define CSR_ALLOW_DEVICE_CONFIGURATION  (1 << 7)
```
とそれっぽい定義があり、ここに先ほどの値が当てはめられるようです。

ちなみに、先ほどの0x14を２進数に直すと```000010100```	となり
```CSR_ALLOW_TASK_FOR_PID```と```CSR_ALLOW_APPLE_INTERNAL```の部分が1になっていることがわかります。

また、csrutilで設定できる内容とビット列の関係は以下の表となります。

| コマンド | DEVICE | NVRAM | DTRACE | INTERNAL | KERNEL | PID | FS | KEXT | 16進数値 |
|--------|--------|--------|--------|--------|--------|--------|--------|--------|--------|
| enable --no-internal | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0x00 |
| enable | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0x10 |
| enable --without kext | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0x11 |
| enable --without fs | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0x12 |
| enable --without debug | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0x14 |
| enable --without dtrace | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0x30 |
| enable --without nvram | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0x50 |
| disable | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0x77 |


## それぞれのフラグの意味
ここからは少し予測が入りますが、それぞれのフラグが意味する内容を整理してみます。

### CSR_ALLOW_UNTRUSTED_KEXTS
未署名のkextの読み込み制限を解除するフラグです。

kextはKernel Extentionの略でデフォルトのカーネルを拡張する為のモジュールです。
例えば、ドライバがこれに該当します。

10.10以降からkextには署名が必須となっているようです。

### CSR_ALLOW_UNRESTRICTED_FS
ファイルシステムに対する制限を解除するためのフラグです。
これは有名ですね。

この制限により特定のフォルダではファイルの作成、更新はroot権限でも不可能になっています。

また、保護される場所、例外の場所はそれぞれ
```/System/Library/Sandbox/rootless.conf```
```/System/Library/Sandbox/Compatibility.bundle/Contents/Resources/paths```
で確認することができます。

### CSR_ALLOW_TASK_FOR_PID
task_for_pid()が利用できるようになるフラグです。

これは何のための関数かというと
> an inspector process now depends on the security framework to authorize use of the task_for_pid system service which gives a process the capability to control another process.

とあるので、どうやら別のプロセスを操作するときに利用する関数みたいです。

### CSR_ALLOW_KERNEL_DEBUGGER
おそらく、カーネルコードの変更制限を解除するためのフラグです。
これは、csrutilでは設定できない項目です。
カーネルをデバッグする機会はそうそうないと思うので問題ないでしょう。

### CSR_ALLOW_APPLE_INTERNAL
以下のコードを見る限り、SIPが有効なら基本的に1となるフラグらしいです。

```
 * rootless=0
 *    no effect
 * rootless=1
 *    csr_allow_internal = 0
```

ここが0の場合、他のフラグが0でも意味が無いのだと思われます。

### CSR_ALLOW_UNRESTRICTED_DTRACE
dtraceの実行制限を解除するためのフラグです。

dtraceはプロセスの動作を追跡、監視するためのコマンドです。
実際に実行してみたところ、一部の追跡コマンドは権限がないとしてはじかれました。

### CSR_ALLOW_UNRESTRICTED_NVRAM
nvramの実行制限を解除するためのフラグです。
nvramコマンドを通じて内容を変更できるようになります。

ここが変更できるということはcsr-active-configを変更できるということになるので、SIPの意味がほとんどなくなってしまいます。
基本的に無効にしない方がいいフラグでしょう。

### CSR_ALLOW_DEVICE_CONFIGURATION
調べてみましたが、何に使われているのかはよくわかりませんでした。
これは、csrutilでは設定できない項目です。


## XtraFinderはなぜ動くようになったのか
さて、ここまで調べれば、なぜExtraFinderが最初のコマンドで動くようになったのかが説明できますね。

XtraFinderはFinderを拡張するアプリケーション、つまり別プロセスの操作が必要になるのでtask_for_pid()を利用する必要があります。

そのため```--without debug```により```CSR_ALLOW_TASK_FOR_PID```を有効にする必要があった、ということになります。

## 気になること
statusではApple Internalがdisabledとなっていますが、フラグ的には有効となっています。
これがそういう表記なのか、全部有効でないからなのかは今のところ不明です。

## まとめ
最終的に、SIPが何を制限し、また何を解除できるのかがわかりました。

また、最小限の権限を解除することでXtraFinderが利用できるようになっていたことがわかりました。


## 参考リンク
http://www.idelta.info/archives/sip-rootless-internal-in-el-capitan/

http://os-tres.net/blog/2010/02/17/mac-os-x-and-task-for-pid-mach-call/

http://havee.me/mac/2015-10/system-integrity-protection-on-el-capitan.html

http://www.opensource.apple.com/source/xnu/xnu-2782.1.97/bsd/kern/kern_csr.c

http://qiita.com/gamako/items/9980a08a24916f9f98b2