2016-08-24 6 views
1

私は、カスタムバイトコードインタープリタ用のLinuxセキュリティサンドボックスをseccompモードで実装しています。できるだけ攻撃面を最小限に抑えるため、完全にきれいな仮想アドレス空間で実行したいと考えています。私はコードとデータセグメントとスタックを利用できるだけですが、vsyscall、vdso、vvarは必要ありません。Linux vsyscallを無効にするvdar

特定のプロセスでこのページの割り当てを無効にする方法はありますか?

答えて

1

マッピング自体を使用できないようにするには、基本的には、vsyscall/vDSOをグローバルに無効にする必要があります。プログラムがvsyscall/vDSOのシステムコールだけを呼び出せないようにするには、seccompがそれを実行できるようにします。しかしいくつかの注意点が:

https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt x86-64のオン

、vsyscallエミュレーションは、デフォルトで有効になって参照してください。 (。vsyscallsはVDSO呼び出しに レガシーが変異体である)現在、いくつかの奇妙で、vsyscallsはseccompを尊重するエミュレート:

  • SECCOMP_RET_TRAPの戻り値が に与えられたコールのためのvsyscallエントリを指し示すsi_call_addrを設定します 'システムコール'命令の後のアドレスではありません。 コールを再開したいコードは、(a)ret命令がエミュレートされており、(b) がsyscallを再開しようとすると、標準のvsyscall エミュレーションセキュリティチェックが再開され、システムコールが再開されることに気づくはずです 無意味な。 SECCOMP_RET_TRACEの

  • 戻り値は、通常通りトレーサー信号 が、システムコールは orig_raxレジスタを使用して別のシステムコールに変更することはできないであろう。現在エミュレートされている をスキップするためには-1に変更する必要があります。その他の変更は、プロセスを終了することがあります。 トレーサが認識するリッピング値は、システムコールエントリアドレスになります。 これは通常の動作とは異なります。トレーサは リップまたはrspを変更してはいけません。 (プロセスを終了するその他の変更に依存しないでください。 彼らが働くかもしれない。例えば、いくつかのカーネルでは、-ENOSYSを返す )によってのみ、将来のカーネルに存在する が正しくエミュレートされるシステムコールを(選択する。

addrの&〜0x0C00の== 0xFFFFFFFFFF600000をチェックし、この風変わりな振る舞いを検出する(。。SECCOMP_RET_TRACEについて、RIPを使用 SECCOMP_RET_TRAPについて、siginfo-> si_call_addrを使用する)は、他の の状態をチェックしないでください:将来のカーネルはvsyscallを向上させることがエミュレーションと現在の カーネルは、vsyscall = nativeモードでは動作が異なりますが、xFFの命令...これらの の場合、F600 {0,4,8、C} 00はシステムコールになりません。

最近のシステムでは、vsyscallをまったく使用しない可能性があることに注意してください。 は従来の機能であり、標準 syscallsよりもかなり遅いです。新しいコードはvDSOを使用し、vDSO発行のシステムコール は通常のシステムコールと区別できません。

したがって、エミュレートされたvsyscallsはseccompによって制限され、vDSOも同様にseccompによって制限されます。gettimeofday()を無効にすると、制限されたプログラムは、エミュレートされたvsyscall、vDSO、または通常のシステムコールを通じてそのシステムコールを呼び出すことができなくなります。このような方法でseccompに閉じ込めば、作成する攻撃面について心配する必要はありません。

vDSOマッピング自体(システムコールを呼び出す必要はありません)を悪用する可能性がある場合は、プロセス単位で確実に無効にする方法はないと思います。それがリンクされないようにすることはできますが、妥協したバイトコードインタープリタがメモリを割り当てて戻すのを防ぐのは難しいでしょう。しかし、グローバルに無効にするカーネルパラメータvdso=0で起動することができます。そのため、リンクすると何も起こりません。

関連する問題