首页 > 解决方案 > Java 沙盒安全策略

问题描述

我正在关注本教程教程,了解如何在使用插件时实现沙盒。

这是我的主类,我从 Jar 文件加载类并运行接口函数:

import java.io.File;
import java.net.URL;
import java.security.Policy;

public class Main {

    public static void main(String[] args){

        Policy.setPolicy(new SandboxSecurityPolicy());
        System.setSecurityManager(new SecurityManager());


        try {
            File file = new File("JarDummy.jar");
            URL urlJar = file.toURI().toURL();

            ClassLoader pluginLoader = new PluginClassLoader(urlJar);

            Class<?> pluginClass = pluginLoader.loadClass("ZEngine");
            IEngine plugin = (IEngine) pluginClass.newInstance();

            plugin.build("file.txt");

        }catch (Exception e){
            e.printStackTrace();
        }
    }


}

这是我的界面:

public interface IEngine {

    void build(String filename);
}

这是我的插件类加载器:

导入 java.net.URL;导入 java.net.URLClassLoader;

public class PluginClassLoader extends URLClassLoader {
    public PluginClassLoader(URL jarFileUrl) {
        super(new URL[] {jarFileUrl});
    }
}

这是我的策略,如果从插件加载类,则会给予不同的权限:

import sun.plugin.security.PluginClassLoader;
import java.security.AllPermission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.ProtectionDomain;

public class SandboxSecurityPolicy extends Policy {

    @Override
    public PermissionCollection getPermissions(ProtectionDomain domain) {
        if (isPlugin(domain)) {
            return pluginPermissions();
        }
        else {
            return applicationPermissions();
        }
    }

    private boolean isPlugin(ProtectionDomain domain) {
        return domain.getClassLoader() instanceof PluginClassLoader;
    }

    private PermissionCollection pluginPermissions() {
        Permissions permissions = new Permissions(); // No permissions
        return permissions;
    }

    private PermissionCollection applicationPermissions() {
        Permissions permissions = new Permissions();
        permissions.add(new AllPermission());
        return permissions;
    }
}

当我运行主类并且代码执行时plugin.build(),我得到一个带有以下跟踪的 ​​stackoverflow 异常:

*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
Exception in thread "main" java.lang.StackOverflowError
    at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:77)
    at sun.nio.cs.UTF_8.access$200(UTF_8.java:57)
    at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:636)
    at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:691)
    at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:579)
    at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:271)
    at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
    at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
    at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
    at java.io.PrintStream.write(PrintStream.java:526)
    at java.io.PrintStream.print(PrintStream.java:669)
    at java.io.PrintStream.println(PrintStream.java:806)
    at SandboxSecurityPolicy.getPermissions(SandboxSecurityPolicy.java:12)
    at java.security.Policy.implies(Policy.java:721)
    at java.security.ProtectionDomain.implies(ProtectionDomain.java:285)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:450)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1564)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:318)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at SandboxSecurityPolicy.isPlugin(SandboxSecurityPolicy.java:23)
    at SandboxSecurityPolicy.getPermissions(SandboxSecurityPolicy.java:13)

我不确定为什么instanceOf会创建导致此溢出的递归。我感谢您的帮助。谢谢!

更新:我在另一台机器上运行了相同的代码,它运行良好。这似乎是一个 JDK 错误。

标签: javastack-overflowsandbox

解决方案


推荐阅读