デバイスファイルのアクセス制御見直し
さて、新SELinuxばっかやってたけどSELinux Policy Editorの研究も再開。
この中でも,デバイスファイルのアクセス制御の見直しをしよう
そもそもデバイスファイルとは
ドライバとVFSのシステムコール(open,read,writeなど)を繋ぐインターフェース。
つまり以下のようなこと
- ドライバ(メジャー番号、マイナー番号)を識別子としてもつ
- デバイスファイル(メジャー番号、マイナー番号)を関連づけられている
- VFSのシステムコールで、デバイスファイル(例えばメジャー番号10マイナー番号10)を開く
- メジャー番号,マイナー番号に対応づけられたドライバが検索される
- メジャー番号10,マイナー番号10のドライバを発見。
- ドライバ内のVFSのシステムコールの実体が実行される
実際にコード例を見るとわかる。
例:http://www.mech.tohoku-gakuin.ac.jp/rde/contents/linux/drivers/chardev1.html
http://www1.linkclub.or.jp/~zhidao/zlab/computing/rtl_posixio.html
操作の粒度
デバイスに対する操作は、「作成」「削除」「読み」「書き」「ioctl」に分類できる。
それぞれの操作による,想定される脅威
- デバイスの作成
任意のドライバへのアクセス。デバイスファイルは、カーネルとのインターフェースなので。
例:ディスクI/Oをつかさどるドライバのメジャー番号、マイナー番号を使ってデバイスを作ることで、何でもできてしまう。
- デバイスの削除
/dev/null削除。ダミーファイル作成。
例えば、/dev/nullを削除し、/dev/nullという普通のファイルを作れば、/dev/nullに捨てられた情報を見ることができる。
システム破壊。デバイスファイル(/dev/hda1)を削除することで、ディスクにアクセスできなくする
- デバイスの読み込み
デバイスファイルと関連づけられたハードウェア経由の情報漏洩。
- デバイスの書き込み
デバイスファイルと関連づけられたハードウェア経由のデータ書き込み。
- デバイスのioctl
ioctlの動作はデバイスドライバに委ねられているが…パラメータの制御に使うのが一般的と思われる。パラメータを変更することで可用性の低下などが考えられる。
アクセス制御対象の粒度
- 粒度が粗い場合の問題点
特権「mknod」方式
「デバイスを作成する特権」を用意し、その特権がない限りデバイスは作れない、とする。
しかし、逆にこの特権がある人は、書き込み可能ディレクトリにデバイスを作れる。
発生する問題は、「多くの人が読み込みディレクトリ」にデバイスを作っちゃうと、
デバイス経由で情報漏洩が発生する。
- 一番ベストなもの
個々のファイルに、デバイスは別にパーミッションを設定できるようにする。
つまり、allowのパーミッション統合からデバイスは取り除く。
で
allowdev /dev r,w,s;
のように別書式を用意する。
→設定が面倒になってしまう…
Simplified policyのデバイス保護の設計
- パーミッションの種類
s: getattr
r: 読み込み
x: ioctl
o: 書き込み(overwrite)
c: 作成
e: 消去
t: setattr
a: 追記(デバイスでは意味なしたぶん。)
w(大雑把パーミッション)= o+c+e+t+a
- 普通は,/devにしかデバイスは格納されないことに着目。
allow /dev
変換後ポリシのオブジェクトクラスに自動的にchr_file,blk_fileを含むようにする。
それ以外のところでは、chr_file,blk_fileを含んだallowは出力しない。
こうすれば、/dev以下について,
「生成(c)」「削除(e)」「書き込み(o)」「読み込み(r)」の粒度で、デバイスファイルのアクセス制御可能。
一方、/dev以外には、デバイスを作成することができないことを保障できる。
- dev以外にデバイスを配置したい時はどうする
デバイスファイルの位置を指定できるようにする
allowdev -root <デバイスのディレクトリ>;
allowdev -root /dev;
allowdev -root /chroot/dev;
↑を記述することで,
allow /chroot/dev/hogehoge r,w;
としたとき, chr_file,blk_fileも含まれるようになる。
つまり、<デバイスのディレクトリ>が、デバイス専用と認識
されるようになる(TOMOYO Linuxのデバイス専用FSマウントみたいなもの)
通常は、globalにallowdev -root /dev;
が書かれている。
- パーミッションwしか使えない場合の安全策(いるかなぁ)
おおざっぱパーミッション「w」は、作成(c)、消去(e)、書き込み(o)を許可してしまう。
先ほどのパーミッションc,e,oは、詳細パーミッションで、これを使わない環境も考えられる。
そんな環境では、「w」パーミッションを使うしかない。
allowdev create;
allowdev unlink;
という特権を用意する。(unlinkはいらない?)
これらが許可されない限り,/dev以下の生成,消去は許可されない。
- allowtty/ptsはallowdev書式に統合する
allowtty/ptsは、/dev/tty* /dev/pts/*のアクセス制御するためのもの。
デバイス設定なので、allowdevに統合する。
tty/ptsデバイスは、所有者のロールによって識別される。
ファイル名ベースのアクセス制御は難しい。
allowdev -tty
allowdev -pts
- ワイルドカード指定
デバイスファイルは、似たような名前が沢山ある。
allow /dev/hda* みたいにワイルドカードか正規表現にできる必要もあるだろう