1

インポート、CPU 時間、および割り当てられたバイトを制限することでユーザー関数を安全に実行できるように、Janino を使用してスクリプト サンドボックスを構築しようとしています。

Rhino (javascript コード用) には、環境を構築するときにユーザーがXを定義できるX命令 ごとに呼び出される、observeInstructionCount(Context ctx, int instructionCount)という名前の関数があります。

この関数では、次のようなことができます。

/**
 * This method is called every {@code instructionsBeforeObserve} and it is
 * used to check if the current execution has exceded the {@code maxCpuTime}
 * or the {maxMemory}. If so, an {@link java.lang.Error} is thrown.
 *
 */
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
    SafeContext sctx = (SafeContext) cx;
    //Check CPU Time
    if (getMaxCpuTime() > 0) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - sctx.getStartTime() > getMaxCpuTime()) {
            throw new Error("Max CPU Time limit of " + getMaxCpuTime() + " was exceeded");
        }
    }
    //Check Memory Consumption
    if (getMaxMemory() > 0 && threadMonitor != null) {
        if (sctx.getStartMemory() <= 0) {
            sctx.setStartMemory(threadMonitor.getThreadAllocatedBytes(sctx.getThreadId()));
        } else {
            long currentAllocatedBytes = threadMonitor.getThreadAllocatedBytes(sctx.getThreadId());
            if ((currentAllocatedBytes - sctx.getStartMemory()) >= getMaxMemory()) {
                throw new Error("Max Memory limit of " + getMaxMemory() + " was exceeded");

            }
        }
    }
}

実行時間と割り当てられたバイトを監視します。

ユーザーがループ (例: while(true) {} ) を作成しても、この関数は最終的に呼び出され、以前に定義された実行時間を超えた場合、エラーがスローされ、スクリプトの実行が停止します。

Janinoを使用してこの動作を再現しようとしていますが、スクリプトの実行を監視する同様のメカニズムがありません。ユーザーがブロッキング関数を呼び出した場合、スクリプトを実行しているスレッドで thread.stop() を突然呼び出す以外に、スクリプトを停止する方法がありません。これは問題になる可能性があります。(私が知る限り) thread.interrupt() のような他の呼び出しは、ブロッキング呼び出しを中断しません。

この問題を解決するにはどうすればよいですか?

4

0 に答える 0