6

ptrace()私が開始し、そのすべての子(孫などを含む)が作成するプロセスを実行して、サンドボックスを実装したいと思います。親プロセス、ptrace()つまりスーパーバイザー。単純なCまたはPythonプログラムであり、概念的には、ファイルシステムアクセス(パス名とアクセス方向(読み取りまたは書き込み)およびソケットアクセス(ソケットの作成を禁止するなど)に基づく)を制限します。

ptrace()dプロセスとその子が(再帰的に)サンドボックスをバイパスできないようにするには、何に注意する必要がありますか?fork()競合状態を回避するために監督者がその時に行うべき特別なことはありますか?rename()競合状態なしで子プロセスなどからのファイル名引数を読み取ることは可能ですか?

これが私がすでに計画していることです:

  • PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONEfork()ingするときに(いくつかの)人種の条件を避けるために
  • デフォルトですべてのシステムコールを禁止し、許可されたシステムコールのホワイトリストを作成します
  • *at()システムコールバリアント(などopenat)が適切に保護されていることを確認してください

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

4

2 に答える 2

12

主な問題は、ファイル名などの多くの 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"

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

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

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

于 2010-12-12T12:57:35.020 に答える
3

ptrace は事後通知しか受け取らないのですか? システムコールの発生を実際に停止する機会はないと思います。何か「悪」を見たら、できるだけ早くシステムコールを殺すだけです。

SELinux や AppArmor のような、不正な呼び出しが 1 つも通過しないことを保証できるものを探しているようです。

于 2010-12-11T01:22:31.273 に答える