AccessController doPrivileged可以在未授予ModifyThreadGroup权限时创建线程吗? [英] AccessController doPrivileged can create thread when modifyThreadGroup not granted?

查看:101
本文介绍了AccessController doPrivileged可以在未授予ModifyThreadGroup权限时创建线程吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图禁止在AccessController.doPriviliged()方法中创建线程.下面的方法创建并运行线程.我使用-Djava.security.manager来运行它.根据此链接,如果未授予modifyThreadGroup,那么应该禁止创建线程吗?

I am trying to prohibit thread creation in an AccessController.doPriviliged() method. The method below creates and runs the thread. I run this with -Djava.security.manager. According to this link, if modifyThreadGroup is not granted, then Thread creation should be disallowed?

http://docs.oracle.com/javase/7/docs/technotes/guides/security/permissions.html

有人能启发我为什么会发生这种情况,以及禁止使用AccessController创建线程的正确方法吗?

Can anyone enlighten me as to why this is happening and the correct way to disallow Thread creation using AccessController?

// .java.policy in $UserHome:

grant codeBase "file:/C:/-" {
    permission java.security.AllPermission;
};


public class ThreadTest {
  public void testModifyThreadGroup() {

    // grant no permissions
    Permissions perms = new Permissions();

    ProtectionDomain domain = new ProtectionDomain(
            new CodeSource( null, (Certificate[]) null ), perms );
    AccessControlContext _accessControlContext = new AccessControlContext(
            new ProtectionDomain[] { domain } );

    try {
        AccessController.doPrivileged(new PrivilegedExceptionAction(){
            @Override
            public Object run() {
                try {
                    // modifyThreadGroup not granted, so should not be able
                    // to call Thread constructor???
                    Thread t = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("Thread.run()");
                        }
                    });
                    t.run();
                } catch (Exception ex) {
                    System.out.println("Error running thread: " + ex);
                }
                return null;
        }}, _accessControlContext);
    } catch(Exception e) {
        System.out.println("Access Error running doPrivileged: " + e);
    }
  }
}

推荐答案

创建或启动线程时,唯一要做的检查是检查并查看调用线程是否具有修改线程组的权限.您可能会认为,这没有检查调用线程是否具有"modifyThreadGroup"权限.

The only check done when a thread is created or started is to check and see if the calling thread has permission to modify the thread group. This does not, as you might think, check to see if the calling thread has the permission "modifyThreadGroup".

代替它的工作(默认情况下)将始终授予访问权限,除非所讨论的线程组是系统线程组,在这种情况下,将检查"modifyThreadGroup"权限.有问题的线程组几乎永远不会是系统线程组.

Instead what it does (by default) is to always grant access unless the ThreadGroup in question is the system thread group in which case the "modifyThreadGroup" permission is checked. The ThreadGroup in question is almost never the system thread group.

您将必须使用自己的实现来扩展SecurityManager并进行某种形式的检查.您可能应该组成自己的新权限.举例来说,我使用一个现有权限实施了黑客攻击,我知道线程将具有默认策略给定的(exitVM):

You will have to extend SecurityManager with your own implementation and do some kind of check of your own. You should probably make up your own new permission. As an example I implemented a hack using an existing permission I knew threads would have (exitVM) given the default policy:

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;

public class QuickTest {

    public static class NoThreadsSecurityManager extends SecurityManager {

        public void checkAccess(ThreadGroup g) {
            super.checkAccess(g);
            checkPermission(new RuntimePermission("exitVM"));
        }

    }

    public static class SimpleRunnable implements PrivilegedExceptionAction<Object> {
        @Override
        public Object run() {
            try {
                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Thread.run()");
                    }
                });
                t.start();
                t.join();
            } catch (Exception ex) {
                System.out.println("Error running thread: " + ex);
            }
            return null;
        }
    }

    public void testModifyThreadGroup() {

        // grant no permissions
        Permissions perms = new Permissions();

        ProtectionDomain domain = new ProtectionDomain(new CodeSource(null, (Certificate[]) null), perms);
        AccessControlContext _accessControlContext = new AccessControlContext(new ProtectionDomain[] { domain });

        try {
            AccessController.doPrivileged(new SimpleRunnable(), _accessControlContext);
        } catch (Exception e) {
            System.out.println("Access Error running doPrivileged: " + e);
        }

        new SimpleRunnable().run();

    }

    public static void main(String[] args) {
        System.setSecurityManager(new NoThreadsSecurityManager());
        new QuickTest().testModifyThreadGroup();
    }

}

这篇关于AccessController doPrivileged可以在未授予ModifyThreadGroup权限时创建线程吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆