1

我正在尝试使用 Janino 构建一个脚本沙箱,以便我可以通过限制导入、CPU 时间和分配的字节来安全地执行用户函数。

在 Rhino(用于 javascript 代码)中,我有一个名为observeInstructionCount(Context ctx, int instructionCount)的函数, 它在每个X指令中调用,其中X可以由用户在构建环境时定义。

在这个函数中,我可以做这样的事情:

/**
 * 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