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 中的初始化字段是做啥用的?的主要内容,如果未能解决你的问题,请参考以下文章