java.lang.SecurityManager 中的初始化字段是做啥用的?

Posted

技术标签:

【中文标题】java.lang.SecurityManager 中的初始化字段是做啥用的?【英文标题】:What is the initialized field in java.lang.SecurityManager for?java.lang.SecurityManager 中的初始化字段是做什么用的? 【发布时间】:2018-07-01 06:20:45 【问题描述】:

java.lang.SecurityManager中,有一个名为initialized的布尔字段。

public class SecurityManager 

    /*
     * Have we been initialized. Effective against finalizer attacks.
     */
    private boolean initialized = false;
    //some code
    /**
     * Constructs a new <code>SecurityManager</code>.
     *
     * <p> If there is a security manager already installed, this method first
     * calls the security manager's <code>checkPermission</code> method
     * with the <code>RuntimePermission("createSecurityManager")</code>
     * permission to ensure the calling thread has permission to create a new
     * security manager.
     * This may result in throwing a <code>SecurityException</code>.
     *
     * @exception  java.lang.SecurityException if a security manager already
     *             exists and its <code>checkPermission</code> method
     *             doesn't allow creation of a new security manager.
     * @see        java.lang.System#getSecurityManager()
     * @see        #checkPermission(java.security.Permission) checkPermission
     * @see java.lang.RuntimePermission
     */
    public SecurityManager() 
        synchronized(SecurityManager.class) 
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) 
                // ask the currently installed security manager if we
                // can create a new one.
                sm.checkPermission(new RuntimePermission
                                   ("createSecurityManager"));
            
            initialized = true;
        
    
    //some code

显然,初始化字段默认为false,但如果实例化通过安全检查并成功,则初始化字段将分配为true。初始化的字段上面只有注释,说对finalizer攻击有效,没有对该字段的描述。

我在互联网上搜索了finalizer attacks。我的理解是,我们不应该依赖可以被不受信任的代码覆盖的方法。但是它与初始化的字段有什么关系呢?我仍然可以继承java.lang.SecurityManager,并且如果安装了SecurityManager但允许通过反射访问私有字段,则应该可以编辑初始化字段。那么它如何有效对抗终结器攻击呢?

【问题讨论】:

【参考方案1】:

这是一种较旧的保护技术: https://www.ibm.com/developerworks/java/library/j-fv/j-fv-pdf.pdf

简而言之 - 终结器攻击是当您覆盖对象的 finalize() 方法时,该方法用作 GC 将调用以释放本机资源的析构函数。但是一旦你继承,或者用反射覆盖它 - 原始代码的不变量/“承诺”不再成立。

如何避免攻击

在 Java 语言规范 (JLS) 第三版发布之前 在 Java SE 6 中实现,避免攻击的唯一方法 - 使用 initialized 标志,禁止子类化,或创建final 终结器——是不令人满意的解决方案。

使用初始化标志:

避免攻击的一种方法是使用initialized 标志,即 正确创建对象后设置为 true。中的每个方法 该类首先检查是否设置了 initialized 并抛出一个 如果不是,则例外。这种编码写起来很累,是 容易被意外遗漏,并且不会阻止攻击者 子类化方法。

【讨论】:

以上是关于java.lang.SecurityManager 中的初始化字段是做啥用的?的主要内容,如果未能解决你的问题,请参考以下文章