JDK-8236582 : (fc) FileChannel.map fails with InternalError when security manager enabled
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 14
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86_64
  • Submitted: 2019-12-30
  • Updated: 2023-08-15
  • Resolved: 2020-01-09
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 14 JDK 15
14 b32Fixed 15Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
openjdk 14-ea 2020-03-17
OpenJDK Runtime Environment (build 14-ea+29-1384)
OpenJDK 64-Bit Server VM (build 14-ea+29-1384, mixed mode, sharing)

Linux 4.15.0-72-generic #81-Ubuntu

A DESCRIPTION OF THE PROBLEM :
With security on, FileChannel.map fails with InternalError:

Exception in thread "main" java.lang.InternalError: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
	at java.base/jdk.internal.misc.ExtendedMapMode.<clinit>(ExtendedMapMode.java:46)
	at java.base/sun.nio.ch.FileChannelImpl.isSync(FileChannelImpl.java:1119)
	at java.base/sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:994)
	at FileChannelExtendedMapModeBug.main(FileChannelExtendedMapModeBug.java:11)
Caused by: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
	at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
	at java.base/java.security.AccessController.checkPermission(AccessController.java:1036)
	at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:408)
	at java.base/java.lang.invoke.MethodHandles.privateLookupIn(MethodHandles.java:223)
	at java.base/jdk.internal.misc.ExtendedMapMode.<clinit>(ExtendedMapMode.java:42)

This works fine in java 13. It was encountered during Elasticsearch CI here: https://github.com/elastic/elasticsearch/issues/50512 and can be reproduced with following program:

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;

public class FileChannelExtendedMapModeBug {
    public static void main(String[] args) throws IOException {
        Path tempFile = Files.createTempFile("test", "test");
        FileChannel ch = FileChannel.open(tempFile);
        System.setSecurityManager(new SecurityManager());
        ch.map(FileChannel.MapMode.READ_ONLY, 0, 0);
    }
}

The static initializer in ExtendedMapMode seems to be the cause, requiring elevated permissions. By map'ing a file before enabling security, the issue goes away.

REGRESSION : Last worked in version 13.0.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the program above using java 14 (fails) and java 13 (works).

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The ability to use FileChannel.map with security on.
ACTUAL -
Program to reproduce gave this:

Exception in thread "main" java.lang.InternalError: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
	at java.base/jdk.internal.misc.ExtendedMapMode.<clinit>(ExtendedMapMode.java:46)
	at java.base/sun.nio.ch.FileChannelImpl.isSync(FileChannelImpl.java:1119)
	at java.base/sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:994)
	at FileChannelExtendedMapModeBug.main(FileChannelExtendedMapModeBug.java:13)
Caused by: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
	at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
	at java.base/java.security.AccessController.checkPermission(AccessController.java:1036)
	at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:408)
	at java.base/java.lang.invoke.MethodHandles.privateLookupIn(MethodHandles.java:223)
	at java.base/jdk.internal.misc.ExtendedMapMode.<clinit>(ExtendedMapMode.java:42)
	... 3 more

Elasticsearch CI gave this:

org.elasticsearch.test.CorruptionUtilsTests > testLuceneCheckIndexIgnoresLast4Bytes FAILED	
    java.lang.InternalError: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")	
        at __randomizedtesting.SeedInfo.seed([F5460B55BBCC2378:70578525AA44A9A7]:0)	
        at java.base/jdk.internal.misc.ExtendedMapMode.<clinit>(ExtendedMapMode.java:46)	
        at java.base/sun.nio.ch.FileChannelImpl.isSync(FileChannelImpl.java:1119)	
        at java.base/sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:994)	
        at org.apache.lucene.mockfile.FilterFileChannel.map(FilterFileChannel.java:121)	
        at org.apache.lucene.mockfile.FilterFileChannel.map(FilterFileChannel.java:121)	
        at org.apache.lucene.mockfile.FilterFileChannel.map(FilterFileChannel.java:121)	
        at org.apache.lucene.store.MMapDirectory.map(MMapDirectory.java:267)	
        at org.apache.lucene.store.MMapDirectory.openInput(MMapDirectory.java:242)	
        at org.apache.lucene.util.LuceneTestCase.slowFileExists(LuceneTestCase.java:2862)	
        at org.apache.lucene.store.MockDirectoryWrapper.openInput(MockDirectoryWrapper.java:747)	
        at org.apache.lucene.store.FilterDirectory.openInput(FilterDirectory.java:100)	
        at org.apache.lucene.store.FilterDirectory.openInput(FilterDirectory.java:100)	
        at org.apache.lucene.store.Directory.openChecksumInput(Directory.java:157)	
        at org.apache.lucene.index.SegmentInfos.readCommit(SegmentInfos.java:287)	
        at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:846)	
        at org.elasticsearch.index.store.Store.newAppendingIndexWriter(Store.java:1541)	
        at org.elasticsearch.index.store.Store.associateIndexWithNewTranslog(Store.java:1448)	
        at org.elasticsearch.index.shard.StoreRecovery.internalRecoverFromStore(StoreRecovery.java:416)	
        at org.elasticsearch.index.shard.StoreRecovery.lambda$recoverFromStore$0(StoreRecovery.java:94)	
        at org.elasticsearch.action.ActionListener.completeWith(ActionListener.java:285)	
        at org.elasticsearch.index.shard.StoreRecovery.recoverFromStore(StoreRecovery.java:92)	
        at org.elasticsearch.index.shard.IndexShard.recoverFromStore(IndexShard.java:1841)	
        at org.elasticsearch.index.shard.IndexShardTestCase.recoverFromStore(IndexShardTestCase.java:799)	
        at org.elasticsearch.index.shard.IndexShardTestCase.recoverShardFromStore(IndexShardTestCase.java:550)	
        at org.elasticsearch.index.shard.IndexShardTestCase.newStartedShard(IndexShardTestCase.java:512)	
        at org.elasticsearch.index.shard.IndexShardTestCase.newStartedShard(IndexShardTestCase.java:499)	
        at org.elasticsearch.index.shard.IndexShardTestCase.newStartedShard(IndexShardTestCase.java:477)	
        at org.elasticsearch.test.CorruptionUtilsTests.testLuceneCheckIndexIgnoresLast4Bytes(CorruptionUtilsTests.java:45)	
        Caused by:	
        java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")	
            at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)	
            at java.base/java.security.AccessController.checkPermission(AccessController.java:1036)	
            at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:408)	
            at java.base/java.lang.invoke.MethodHandles.privateLookupIn(MethodHandles.java:223)	
            at java.base/jdk.internal.misc.ExtendedMapMode.<clinit>(ExtendedMapMode.java:42)	
            ... 27 more

---------- BEGIN SOURCE ----------

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;

public class FileChannelExtendedMapModeBug {
    public static void main(String[] args) throws IOException {
        Path tempFile = Files.createTempFile("test", "test");
        FileChannel ch = FileChannel.open(tempFile);

        System.setSecurityManager(new SecurityManager());
        ch.map(FileChannel.MapMode.READ_ONLY, 0, 0);
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use FileChannel.map before enabling security.


Comments
URL: https://hg.openjdk.java.net/jdk/jdk14/rev/eccb8316306d User: bpb Date: 2020-01-09 16:44:38 +0000
09-01-2020

This is JEP 352. ExtendedMapMode needs to use privateLookupIn in a privileged block. I've attached a patch (ExtendedMapMode.java.patch) with the minimal patch to fix this. [~adinn] This is a must-fix for JDK 14. If you don't have the cycles to take it when please re-assign it to me and I'll make sure it gets fixed before RDP2 starts.
06-01-2020

Reproduced the error with 14 on Oracle Linux.
30-12-2019