Extending URLClassLoader and overriding getPermissions does not work

a 夏天 提交于 2020-01-15 06:29:11

问题


When trying to implement a sandbox in a plugin-like environment, I came accross https://stackoverflow.com/a/5580239/2057294 which seems to be exactly what I want, however I am unable to get it working, what am I doing wrong?

I have the following setup:

final class ModURLClassLoader extends URLClassLoader {
    ModURLClassLoader(final URL[] urls) {
        super(urls);
    }

    ModURLClassLoader(final URL[] urls, final ClassLoader parent) {
        super(urls, parent);
    }   

    ModURLClassLoader(final URL[] urls, final ClassLoader parent, final URLStreamHandlerFactory factory) {
        super(urls, parent, factory);
    }

    @Override
    protected PermissionCollection getPermissions(final CodeSource codesource) {
        PermissionCollection permissionCollection = super.getPermissions(codesource);
        //give no permissions to the codesource
        return permissionCollection;
    }

    @Override
    protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            int i = name.lastIndexOf('.');
            if (i != -1) {
                sm.checkPackageAccess(name.substring(0, i));
            }
        }
        return super.loadClass(name, resolve);
    }
}

The idea here is that code loaded through the ModURLClassLoader may have no permissions at all. I do want to be able to add extra permissions statically in case I block some permissions which a mod would generally want to have.

Then I load up my classes via the following:

public class JavaMod extends LoadableMod {
    private ECSMod ecsMod;

    private ModURLClassLoader modUrlClassLoader;

    JavaMod(final Path modDirectory) throws ModNotLoadableException {
        super(modDirectory);
    }

    @Override
    protected void load0() throws ModNotLoadableException {
        try {
            Properties properties = ModLoaderHelper.getConfiguration(modDirectory);
            String jarName = properties.getProperty("jar");
            String entryPoint = properties.getProperty("entryPoint");

            Path jarPath = modDirectory.resolve(jarName);

            try {
                modUrlClassLoader = AccessController.doPrivileged((PrivilegedExceptionAction<ModURLClassLoader>)() -> new ModURLClassLoader(new URL[] { jarPath.toUri().toURL() }, getClass().getClassLoader()));
            } catch (PrivilegedActionException ex) {
                throw new ModNotLoadableException(ex);
            }            
            Class<?> clazz = Class.forName(entryPoint, false, modUrlClassLoader);
            if (!ECSMod.class.isAssignableFrom(clazz)) {
                throw new ModNotLoadableException(clazz + " does not implement ECSMod");
            }
            this.ecsMod = (ECSMod)clazz.newInstance();
        } catch (Exception ex) {
            throw new ModNotLoadableException(ex);
        }
    }

    @Override
    protected void unload0() {
        try {
            modUrlClassLoader.close();
        } catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    @Override
    protected ECSGame createGame0() {
        ECSGame ecsGame = new ECSGame();
        ecsMod.setupGame(ecsGame);
        return ecsGame;
    }
}

Which loads an untrusted JAR that has a class that implements ECSMod, I have confirmed that both the clazz and ecsMod belong to an instance of ModURLClassLoader.

Then the malicious code:

public final class UntrustedEvilMod implements ECSMod {
    @Override
    public void setupGame(final ECSGame game) {
        System.exit(0);
    }
}

Where ECSMod and ECSGame are classes that belong to the plugin (also called mod) API and reside in the original classloader.

I'm running this without a security manager, as I believe that this would be unnecessary in this context? As the ModURLClassLoader defines the security.

Why is this not working, meaning that it still causes the program to exit, whereas I would've wanted an AccessControlException?

来源:https://stackoverflow.com/questions/26340118/extending-urlclassloader-and-overriding-getpermissions-does-not-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!