ファイルシステムでのプログラムの実行を無効にする場合は、noexec
マウントオプションを使用できます。
ただし、これは動的ライブラリloaded throughdlopen()
では機能しません。それで、naclまたはseccompでそれを行う方法は何ですか? (これは、信頼されていないバイトコードサンドボックス用です。ユーザーがアップロードした共有ライブラリを実行できないようにしたい)
同時に、gconvのようなライブラリはtheir.so
モジュールを実行できる必要があります。
プログラムによる他のプログラムのfork()ingまたはexec()utingはすでに無効になっています。
ただし、これは動的ライブラリでは機能しません。
動的ライブラリに対しては機能します。共有オブジェクトがnoexecオプションでマウントされたパーティションにある場合、それはロードできません。そうでない場合、noexec
はまったく役に立たなくなります。
_$ grep -E '/tmp |ext4' /proc/mounts
/dev/mapper/root_crypt / ext4 rw,nodev,noatime,data=ordered 0 0
tmpfs /tmp tmpfs rw,nosuid,nodev,noexec,noatime,size=2031200k 0 0
$ cat > main.c
#include <stdio.h>
void main(void)
{
printf("%d\n", getpid());
}
$ gcc -o main main.c
$ ./main
4950
$ cat > shared.c
int getpid(void)
{
return 1;
}
$ gcc -shared -fPIC -o shared.so shared.c
$ LD_PRELOAD=./shared.so ./main
1
$ mv shared.so /tmp
$ LD_PRELOAD=/tmp/shared.so ./main
ERROR: ld.so: object '/tmp/shared.so' from LD_PRELOAD cannot be preloaded (failed to map segment from shared object): ignored.
4978
_
信頼できない共有オブジェクトの実行を防止するためにseccompを使用したい場合は、mmap()
、mprotect()
、および明らかにexecve()
への呼び出しを制限することでそれを行うことができます。プロセスが_PROT_EXEC
_で何もマップできないことを確認してください。ファイル記述子を使用して任意のデータをmmap()
に渡すことができ、mprotect()
はメモリの任意のページの権限を変更して実行可能にすることができるため、ファイルを制限するだけでは不十分です。さらに、この例はホワイトリストではなくブラックリストであるため、seccompサンドボックスから抜け出すために使用できるため、ptrace()
引数へのアクセスを拒否する必要もあります。
_rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mmap), 1,
SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
if (rc == -1)
goto out;
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCESS), SCMP_SYS(mprotect), 1,
SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
if (rc == -1)
goto out;
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCESS), SCMP_SYS(execve), 0);
if (rc == -1)
goto out;
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1,
SCMP_A0(SCMP_CMP_EQ, PTRACE_POKEUSER));
if (rc == -1)
goto out;
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1,
SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGS));
if (rc == -1)
goto out;
rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1,
SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGSET));
if (rc == -1)
goto out;
_
おそらく私が考えていなかったこのseccompスニペットをバイパスする方法がおそらくあるので、これはそれが何をするのかをあなたに与えるためだけです。
私はNaClを使用したことがないので、それを使用して実行を制限する方法はわかりません。