3

私はプログラミングコンテストの採点者を開発しています。基本的に、採点者は「分離された」プロセスでソリューションプログラムを実行する必要があります。したがって、有害なシステムコール(system()、fork()など)を呼び出さないようにするソリューションが必要です。これを実現するためにptrace()を使用できますか?

4

2 に答える 2

1

私は2つの可能な解決策があると思います:

  1. LD_PRELOADメカニズムを使用して「shim」を作成し、停止するシステムコールを置き換えます。
  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;
}
于 2011-01-16T11:59:54.343 に答える
0

はい、ptrace()を使用して、PTRACE_SYSCALLオプションを使用して特定のシステムコールをブロックできます。この機能を使用したプロジェクトは次のとおりです。

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

Linuxのみを対象とする場合は、代わりにseccompをお勧めします。これは、特定のシステムコールをホワイトリストに登録/ブラックリストに登録するか、引数を制限するためのより高速な手法です。

別の方法は、Googleのネイティブクライアントです。このプロジェクトは、アプリケーションサンドボックスのクロスプラットフォーム実装を提供します。

また、DockerやLXCなどのコンテナー内で非特権ユーザーとしてアプリケーションを実行して、被害を制限することもできます。

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

于 2016-06-01T23:30:40.227 に答える