JDK-8150468 : ClassCircularityError on error in security policy file
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-02-23
  • Updated: 2016-10-17
  • Resolved: 2016-05-16
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.

To download the current JDK release, click here.
JDK 9
9 b120Fixed
Related Reports
Relates :  
Relates :  
Description
If a error occurs while parsing the java policy file it causes a ClassCircularityError.  Mostly likely due to recursion initializing locale specific information for the exception message.

java -Djava.security.manager -Djava.security.policy==src/examples/oracle/error.policy Main
Exception in thread "main" java.lang.ClassCircularityError: sun/util/resources/provider/NonBaseLocaleDataMetaInfo
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:372)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:368)
	at java.util.ServiceLoader$LazyIterator.access$700(ServiceLoader.java:321)
	at java.util.ServiceLoader$LazyIterator$2.run(ServiceLoader.java:405)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:407)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:478)
	at sun.util.cldr.CLDRLocaleProviderAdapter$1.run(CLDRLocaleProviderAdapter.java:76)
	at sun.util.cldr.CLDRLocaleProviderAdapter$1.run(CLDRLocaleProviderAdapter.java:73)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.util.cldr.CLDRLocaleProviderAdapter.<init>(CLDRLocaleProviderAdapter.java:73)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:426)
	at java.lang.Class.newInstance(Class.java:466)
	at sun.util.locale.provider.LocaleProviderAdapter.forType(LocaleProviderAdapter.java:176)
	at sun.util.locale.provider.LocaleProviderAdapter.findAdapter(LocaleProviderAdapter.java:278)
	at sun.util.locale.provider.LocaleProviderAdapter.getAdapter(LocaleProviderAdapter.java:249)
	at java.text.NumberFormat.getInstance(NumberFormat.java:859)
	at java.text.NumberFormat.getInstance(NumberFormat.java:442)
	at java.text.MessageFormat.subformat(MessageFormat.java:1271)
	at java.text.MessageFormat.format(MessageFormat.java:865)
	at java.text.Format.format(Format.java:157)
	at sun.security.provider.PolicyParser$ParsingException.<init>(PolicyParser.java:1347)
	at sun.security.provider.PolicyParser.match(PolicyParser.java:796)
	at sun.security.provider.PolicyParser.parseGrantEntry(PolicyParser.java:558)
	at sun.security.provider.PolicyParser.read(PolicyParser.java:189)
	at sun.security.provider.PolicyFile.init(PolicyFile.java:602)
	at sun.security.provider.PolicyFile.access$300(PolicyFile.java:258)
	at sun.security.provider.PolicyFile$3.run(PolicyFile.java:518)
	at sun.security.provider.PolicyFile$3.run(PolicyFile.java:492)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.security.provider.PolicyFile.initPolicyFile(PolicyFile.java:492)
	at sun.security.provider.PolicyFile.initPolicyFile(PolicyFile.java:477)
	at sun.security.provider.PolicyFile.init(PolicyFile.java:436)
	at sun.security.provider.PolicyFile.<init>(PolicyFile.java:296)
	at java.security.Policy.loadPolicyProvider(Policy.java:207)
	at java.security.Policy.getPolicyNoCheck(Policy.java:177)
	at java.security.ProtectionDomain.implies(ProtectionDomain.java:295)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:446)
	at java.security.AccessController.checkPermission(AccessController.java:894)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:541)
	at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1497)
	at java.lang.ClassLoader$1.run(ClassLoader.java:503)
	at java.lang.ClassLoader$1.run(ClassLoader.java:501)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.lang.ClassLoader.checkPackageAccess(ClassLoader.java:501)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:761)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:152)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:471)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:77)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:365)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:372)
	at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:368)
	at java.util.ServiceLoader$LazyIterator.access$700(ServiceLoader.java:321)
	at java.util.ServiceLoader$LazyIterator$2.run(ServiceLoader.java:405)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:407)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:478)
	at sun.util.cldr.CLDRLocaleProviderAdapter$1.run(CLDRLocaleProviderAdapter.java:76)
	at sun.util.cldr.CLDRLocaleProviderAdapter$1.run(CLDRLocaleProviderAdapter.java:73)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.util.cldr.CLDRLocaleProviderAdapter.<init>(CLDRLocaleProviderAdapter.java:73)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:426)
	at java.lang.Class.newInstance(Class.java:466)
	at sun.util.locale.provider.LocaleProviderAdapter.forType(LocaleProviderAdapter.java:176)
	at sun.util.locale.provider.LocaleProviderAdapter.findAdapter(LocaleProviderAdapter.java:278)
	at sun.util.locale.provider.LocaleProviderAdapter.getAdapter(LocaleProviderAdapter.java:249)
	at java.text.NumberFormat.getInstance(NumberFormat.java:859)
	at java.text.NumberFormat.getInstance(NumberFormat.java:442)
	at java.text.MessageFormat.subformat(MessageFormat.java:1271)
	at java.text.MessageFormat.format(MessageFormat.java:865)
	at java.text.Format.format(Format.java:157)
	at sun.security.provider.PolicyParser$ParsingException.<init>(PolicyParser.java:1347)
	at sun.security.provider.PolicyParser.match(PolicyParser.java:796)
	at sun.security.provider.PolicyParser.parseGrantEntry(PolicyParser.java:558)
	at sun.security.provider.PolicyParser.read(PolicyParser.java:189)
	at sun.security.provider.PolicyFile.init(PolicyFile.java:602)
	at sun.security.provider.PolicyFile.access$300(PolicyFile.java:258)
	at sun.security.provider.PolicyFile$3.run(PolicyFile.java:518)
	at sun.security.provider.PolicyFile$3.run(PolicyFile.java:492)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.security.provider.PolicyFile.initPolicyFile(PolicyFile.java:492)
	at sun.security.provider.PolicyFile.initPolicyFile(PolicyFile.java:477)
	at sun.security.provider.PolicyFile.init(PolicyFile.java:436)
	at sun.security.provider.PolicyFile.<init>(PolicyFile.java:296)
	at java.security.Policy.loadPolicyProvider(Policy.java:207)
	at java.security.Policy.getPolicyNoCheck(Policy.java:177)
	at java.security.ProtectionDomain.implies(ProtectionDomain.java:295)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:446)
	at java.security.AccessController.checkPermission(AccessController.java:894)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:541)
	at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1285)
	at java.lang.System.getProperty(System.java:721)
	at examples.oracle.Main.main(Main.java:6)

Sample Main.java:
public class Main {

    public static void main(String[] args) {
        String javahome = System.getProperty("java.home");
        System.out.printf("java.home: %s%n", javahome);
    }
}

Sample syntax error in policy file:  (Missing trailing semicolon)
grant {
    permission "java.util.PropertyPermission" "java.home", "read"
};



Comments
Review thread: http://mail.openjdk.java.net/pipermail/security-dev/2016-May/013809.html
16-05-2016

I have an initial fix for this. Each time a bad policy file is parsed I add the URL to a Set wrapped in an AtomicReference. Before parsing a policy file URL, the PolicyFile provider impl checks if the URL is in the bad set, and skips it if so. This stops the recursion and the following expected exception is thrown: java.security.policy: error parsing file:/.../policy: line 3: expected [;], found [}] Exception in thread "main" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.home" "read") at java.security.AccessControlContext.checkPermission(java.base@9-internal/AccessControlContext.java:469) at java.security.AccessController.checkPermission(java.base@9-internal/AccessController.java:894) at java.lang.SecurityManager.checkPermission(java.base@9-internal/SecurityManager.java:541) at java.lang.SecurityManager.checkPropertyAccess(java.base@9-internal/SecurityManager.java:1285) at java.lang.System.getProperty(java.base@9-internal/System.java:759) at Main.main(Main.java:4)
04-05-2016

This is a regression introduced when we deprivileged the jdk.localedata module and moved it off the bootclasspath. Prior to that, the AccessControlContext for code in this module would have been null, and that would have caused the security check to be skipped and avoided the recursive policy checking issue. Now the ACC is not null, which triggers a permission check and a recursive parsing of the policy file. So, cause is known, but fix not yet.
03-05-2016