2011-01-16 8 views
3

私はプログラミングコンテストのグレーダーを開発しています。基本的に、グレーダーはソリューションプログラムを「分離された」プロセスで実行する必要があります。だから、システムコール(system()、fork()など)を呼び出さないようにしたい。それを達成するためにptrace()を使用できますか?UNIXのptrace()ブロックの子供のシステムコール

答えて

1

私は2つの可能な解決策があると思います。システムを置き換えるために「シム」を作成するために、LD_PRELOADメカニズムを使用して

  1. を停止したい呼び出します。
  2. setrlimit()を使用して、呼び出し元のプロセスが実行できるものを制限します。残念ながら、これらの制限は、プロセス単位ではなく、ユーザー単位であるように見えます。これにより、正しい値を計算するのが非常に困難になります。

編集:私は最初の選択肢があり、以下に必要なコードが含まれています。 make allを使用してバイナリをビルドした後、make runtestsでテスト:

$ make all 
gcc -fPIC -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 lib.c 
ln -sf libmy.so.1.0 libmy.so.1 
ln -sf libmy.so.1 libmy.so 
gcc -o test test.c 

$ make runtests 
Without LD_PRELOAD: 
./test 
in child: retval=9273 
in parent: retval=0 
With LD_PRELOAD: 
LD_PRELOAD=./libmy.so ./test 
libmy.so fork! 
fork error: error=Operation not permitted (1) 

のMakefile:

all: libs test 

runtests: 
    @echo Without LD_PRELOAD: 
    ./test 
    @echo With LD_PRELOAD: 
    LD_PRELOAD=./libmy.so ./test 


libs: lib.c 
    gcc -fPIC -shared -Wl,-soname,libmy.so.1 -o libmy.so.1.0 lib.c 
    ln -sf libmy.so.1.0 libmy.so.1 
    ln -sf libmy.so.1 libmy.so 

test: test.c 
    gcc -o test test.c 

clean: 
    rm -f test libmy.so.1.0 libmy.so.1 libmy.so lib.o 

lib.c:

#include <stdio.h> 
#include <unistd.h> 
#include <errno.h> 

pid_t fork() 
{ 
    printf("libmy.so fork!\n"); 
    errno = EPERM; 
    return (pid_t)-1; 
} 

test.cの:

#include <stdio.h> 
#include <string.h> 
#include <errno.h> 

int main(int argc, char **argv) 
{ 
    int retval = fork(); 
    if (retval == 0) 
     printf("in parent: retval=%d\n", retval); 
    else if (retval > 0) 
     printf("in child: retval=%d\n", retval); 
    else 
     printf("fork error: error=%s (%d)\n", strerror(errno), errno); 
    return 0; 
} 
+0

ありがとうございますが、「LD_PRELOADメカニズム」についてもう少し説明できますか? – fushar

+0

$ LD_PRELOAD環境変数を共有ライブラリを指すように設定すると、そのライブラリは実行可能ファイル内で設定されたものよりも優先されて使用されます。私はそれがシステムレベルの機能のために働くかどうかわからない。 – trojanfoe

+0

それでは、2番目のオプション:システムコールを防ぐためにsetrlimit()のどのリソースを設定する必要がありますか? – fushar

0

はい]を使える ptrace()は、PTRACE_SYSCALLオプションを使用して特定のシステムコールをブロックします。あなたが唯一のLinuxをターゲットとした場合、私はホワイトリスト/ブラックリスト、特定のシステムコールに、より高速な技術である、代わりにseccompを示唆またはその引数を制限するでしょう

https://github.com/t00sh/p-sandbox/blob/master/p-sandbox.c

: は、ここでは、この機能を使用するプロジェクトです。

代わりに、GoogleのNative Clientとなります。 このプロジェクトは、アプリケーションサンドボックスのクロスプラットフォーム実装を提供します。

ダッカーやLXCなどのコンテナ内で特権のないユーザーとしてアプリケーションを実行して、ダメージを制限することもできます。

LD_PRELOADを単独で使用すると、実行可能ファイルが独自のsyscall実装に付属し、基礎となるlibcをバイパスする可能性があるため、安全ではありません。

関連する問題