0

I have create a simple plugin system that allows others upload their plugin's jar, and the plugin system will load it and execute some code in it.

the plugin system will get a subclass of Function<Input, Output> to execute the loaded plugin logic, but I do not want that Function to create new Thread or do some danger action like System.exit. how can I forbid this action?

I have found the AccessController or SecurityManager in Java, how to use it to implement my intent.

Ian Hu
  • 295
  • 3
  • 7

2 Answers2

4

Like you said, you can add a security Manager. Something like below: You can put your code in try catch block and catch your custom security exception thrown. This code below runs in loop and keeps on calling System.exit(1);

import java.security.Permission;

public class TestPreventSystemExit {

    public static void main(String[] args) {
        forbidSystemExitCall();
        while (true) {
            try {
                System.exit(1);
            } catch (Exception ex) {

            }
        }
    }

    private static class PreventExitException extends SecurityException {
    }

    private static void forbidSystemExitCall() {
        final SecurityManager securityManager = new SecurityManager() {
            public void checkPermission(Permission permission) {
                if (permission.getName().indexOf("exitVM") >= 0) {
                    System.out.println("Why you did this to me? :)");
                    throw new PreventExitException();
                }
            }
        };
        System.setSecurityManager(securityManager);
    }

}
Optional
  • 4,387
  • 4
  • 27
  • 45
1

For System.exit() - see the other answer.

For preventing the starting of threads: possible, but requires to extend the SecurityManager class - see here.

AccessController is more about how a client would write code that is potentially checked. It is not something that you, as the "owner" of the JVM can make usage of (see here). So it doesn't help with your problem.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 1
    The answer that you linked describes how to use a SecurityManager to prevent threads from being started, so I'm not sure how you could conclude that it's not possible. From the answer: "One way to get round this is to subclass java.lang.SecurityManager and override the getThreadGroup method to return the root ThreadGroup. This will then allow you to control whether code can create threads based on whether it has the java.lang.RuntimePermission "modifyThreadGroup"." – Erwin Bolwidt Oct 10 '17 at 13:19
  • Thanks for the quick feedback upon me updating my answer ;-) – GhostCat Oct 10 '17 at 13:37
  • @GhostCat FGITW hmmm ? – Gab Oct 10 '17 at 13:44
  • Sure not, the other guy was way faster than me (at least 30 seconds). – GhostCat Oct 10 '17 at 13:45
  • It is as well possible to do this the `AccessController` / `AccessControlContext` way, via a `ClassLoader` that maps classes it loads to `ProtectionDomain`s that do not have `RuntimePermission` `"exitVM.*"` (which they do, under they default loader). – Uux Oct 11 '17 at 10:38
  • Just to be sure: so you are saying that you "as JVM" owner can use AccessController/ControlContext as well? – GhostCat Oct 11 '17 at 10:43
  • @GhostCat No, what I meant was "you can deny the particular permission without resorting to use of a custom security manager". – Uux Oct 11 '17 at 10:45
  • ...which, I do now realize, doesn't contradict your answer, since you specifically referred to thread modification, which indeed unfortunately requires a custom `SecurityManager` (unless the thread in question belongs to the "system" `ThreadGroup`). By the way, yes, as the "JVM owner", you can also customize `AccessController` & Co., by plugging your own `DomainCombiner` into threads' `AccessControlContext`s (but hardly anyone does that). – Uux Oct 11 '17 at 11:50