2010-12-11 15 views
5

私は起動し、すべての子プロセスが作成するプロセス(孫を含む)をptrace()で実装したいと考えています。 ptrace()親プロセス、すなわち監督者。単純なCまたはPythonプログラムであり、概念的にはパス名とアクセス方向(読み取りまたは書き込み)とソケットアクセス(ソケット作成を禁止するなど)に基づいてファイルシステムのアクセスを制限することになります。 ptrace()のプロセスとその子プロセス(と再帰的に)がサンドボックスをバイパスできないようにするには?fork()競合状態を避けるためにスーパーバイザが特別に行うべきことはありますか?例:rename()競合状態のない子プロセスからの返信はありませんか?Linuxのptraceは安全でないか競合状態になることはありますか?

  • PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE
  • をINGのfork()は、すべてのシステムはデフォルトで呼び出して、許可されるシステムのホワイトリストを構成する
  • は(例えばopenatなど)*at()システムコールの変種が適切であることを確認して呼び出す禁止する場合(一部の)レースcoditionsを避けるために保護された

他に何か注意を払う必要がありますか?

+0

したがって、基本的には、Systrace(http://www.systrace.org/)のptraceベースのバックエンドを複製しようとしていますか? – thkala

+0

はい、私の管理者はsystraceと同様に動作します。残念ながら、systraceは維持されていないように見えますが、それはきれいにコンパイルされません。また、バグのようです(GNUを実行しているGCCをサンドボックス化したとき、 – pts

答えて

11

大きな問題は、ファイル名のような多くのsyscall引数がユーザ空間ポインタとしてカーネルに渡されることです。同時に実行することが許可され、ポインタが指すメモリへの書き込みアクセス権を持つタスクは、スーパバイザによって検査された後、カーネルがそれらに作用する前に、これらの引数を効果的に変更できます。カーネルがポインタをたどるまでに、指し示された内容は、そのメモリにアクセスする別のスケジュール可能なタスク(プロセスまたはスレッド)によって意図的に変更された可能性があります。たとえば:

Thread 1       Supervisor    Thread 2 
----------------------------------------------------------------------------------------------------- 
strcpy(filename, "/dev/null"); 
open(filename, O_RDONLY); 
            Check filename - OK 
                  strcpy(filename, "/home/user/.ssh/id_rsa"); 
(in kernel) opens "/home/user/.ssh/id_rsa" 

一つの方法これはCLONE_VMフラグでclone()を呼び出す許可しないで停止し、それに加えて、書き込み可能なMAP_SHAREDメモリマッピングのいずれかの作成を防ぐ(または少なくともあなたが任意のシステムコールを拒否するように、それらを追跡しますそのようなマッピングからのデータを直接参照しようとします)。また、syscallの処理を許可する前に、そのような引数を共有していないバウンスバッファにコピーすることもできます。これにより、スレッド化されたアプリケーションがサンドボックス内で実行されることを効果的に防止します。

潜在的に危険なすべてのシステムコールのトレースされたグループ内の他のすべてのプロセスが、実際に停止するのを待ってから、システムコールを続行することができます。返された後、SIGCONT(まだ停止していない場合)。言うまでもありませんが、パフォーマンスに大きな影響を与える可能性があります。

(スタックに渡されるsyscall引数にも、共有されているオープンファイルテーブルにも同様の問題があります)。

+0

受け入れ、非常に洞察力、ありがとう! – pts

+0

なぜコピーソリューションはスレッドアプリケーションを防ぎますか?システムコールが「ちょっと」原子的になることを期待しているアプリケーションではありません。 – keppla

+1

@keppla:スレッド化されたアプリケーションでは、すべてのスレッドが同じVMを共有するため、非共有メモリ領域を作成できないためです。コピーから非共有の回避策は、他のプロセスと共有されるメモリ領域内のsyscall引数の場合です。 – caf

3

ptraceは通知後にのみ通知を受け取りますか?私はあなたが実際に起こっていることからシステムコールを止める機会を持っているとは思っていません。

SELinuxやAppArmorのようなものを探しているようですが、違法な呼び出しが1つも届かないことを保証できます。

+0

Linuxでは、PTRACE_SYSEMUがあり、これによってシステムコールを停止できます。また、代替案に言及してくれてありがとう。しかし、バグや競合状態がない限り、SELinuxやAppArmorがより安全になる理由はわかりません。合理的な仮定ですか? – pts

+1

システムコールを無効にする一般的な方法は、それをgetpid(2)に変更することです。 – maat