JDK-8334394 : Race condition in Class::protectionDomain
Type:Bug
Component:core-libs
Sub-Component:java.lang
Priority:P4
Status:Resolved
Resolution:Fixed
Submitted:2024-06-17
Updated:2024-07-29
Resolved:2024-07-22
The Version table provides details related to the release that this issue/RFE will be addressed.
Unresolved : Release in which this issue/RFE will be addressed. Resolved: Release in which this issue/RFE has been resolved. Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.
The read access to static field allPermDomain happens twice, meaning the 2nd read `pd = allPermDomain` may observe a null value and lead to getProtectionDomain returning null.
A pull request was submitted for review.
Branch: master
URL: https://git.openjdk.org/jdk/pull/19752
Date: 2024-06-17 14:51:07 +0000
09-07-2024
[~liach] Yes, this about identity, Weijun has a prototype that uses a holder class.
17-06-2024
Update: It appears that identity is important for ProtectionDomain so we want to avoid double write to the allPermDomain field. Thus we should migrate to a Holder class, which is suitable for backporting as well.
17-06-2024
[~weijun] I recommend changing:
```java
if (allPermDomain == null) {
java.security.Permissions perms =
new java.security.Permissions();
perms.add(SecurityConstants.ALL_PERMISSION);
allPermDomain =
new java.security.ProtectionDomain(null, perms);
}
pd = allPermDomain;
```
to:
```java
pd = allPermDomain; // read only once
if (pd == null) {
java.security.Permissions perms =
new java.security.Permissions();
perms.add(SecurityConstants.ALL_PERMISSION);
pd =
new java.security.ProtectionDomain(null, perms);
allPermDomain = pd;
}
```
this avoids double read, and then the allPermDomain field can be marked with @Stable annotation.
This is similar to the fix for JDK-8261404.
17-06-2024
Reproducer:
import javax.security.auth.Subject;
import java.security.PrivilegedAction;
public class A5 {
public static void main(String[] args) throws Exception {
var ac = (PrivilegedAction<? extends Object>) () -> null;
for (int i = 0; i < 100; i++) {
new Thread(() -> Subject.doAs(null, ac)).start();
}
}
}