Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
511 views
in Technique[技术] by (71.8m points)

multithreading - why java security manager doesn't forbid neither creating new Thread() nor starting it?

do you happen to know explanation why java security manager doesn't forbid creating new threads or starting them? new FileWriter is under security manager, but neither new Thread(), nor threadInstance.start() isn't uneder security manager, and are possible to call.

  1. Wouldn't it be usefull to forbid it ?
  2. Would it be hard to implement ?
  3. Or creating and starting new Thread isn't so relevant to forbid it?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The accepted answer is incorrect: it isn't possible to define a security policy that will prevent code from creating and starting a new thread using the standard Java SecurityManager.

Let's say you have the following code:

public class Test {
  public static void main(String [] args) {
    System.out.println(System.getSecurityManager() != null ? "Secure" : "");
    Thread thread = new Thread(
      new Runnable() { 
        public void run() {
          System.out.println("Ran");
        }
    });
    thread.start();
  }
}

and you run it with the following command:

java -Djava.security.manager -Djava.security.policy==/dev/null Test

it will run just fine and output:

Secure
Ran

even though we set the security policy to /dev/null, which will grant zero permissions to any code. It's therefore impossible to grant fewer permissions to prevent the code from creating that thread.

This is because the the standard java.lang.SecuritManager only performs an permission check if code tries to create a thread in the root ThreadGroup. At the same time, the SecurityManager's getThreadGroup mehtod always returns the current Thread's thread group, which will never be the root thread group, so permission to create a new Thread will always be granted.

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".

So if we now define a subclass of SecurityManager as follows:

public class ThreadSecurityManager extends SecurityManager { 

  private static ThreadGroup rootGroup;

  @Override
  public ThreadGroup getThreadGroup() {
    if (rootGroup == null) {
      rootGroup = getRootGroup();
    }
    return rootGroup;
  }

  private static ThreadGroup getRootGroup() {
    ThreadGroup root =  Thread.currentThread().getThreadGroup();
    while (root.getParent() != null) {
     root = root.getParent();
    }
    return root;
  }
}

and then run our command again, but this time specifying our subclassed ThreadSecurityManager:

java -Djava.security.manager=ThreadSecurityManager -Djava.security.policy==/dev/null Test

We get an exception in our Test class when we try to create the new thread:

Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...