JDK-8191278 : MappedByteBuffer bulk access memory failures are not handled gracefully
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8,9,10,11,12,13
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2017-11-15
  • Updated: 2024-02-06
  • Resolved: 2019-06-25
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 13 JDK 14
13.0.9Fixed 14 b03Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
There are 50+ instances of Unsafe.copyMemory
and 20+ instances of Unsafe.copySwapMemoy in generated Direct*Buffer* code, these accesses are not guarded for graceful dealing as per current implementation or plan (JDK-4454115 , JDK-8154592), this CR is for tracking and handling these cases.
Comments
Fix Request (11u) I'd like to backport this changes to fix crash happens on memory mapped file operations. The patch applies almost cleanly except stubGenerator_arm.cpp due to miss of JEP 340 (One AArch64 Port, Not Two), and some copyright year conflicts. A set of follow up is required to fix build of various platforms (8226871, 8229254, 8226878)
04-08-2021

[~snazarki], can you please add a fix request comment for 11u (or amend the 13u request)? Removing jdk11u-fix-request label for the time being.
03-08-2021

Fix Request (13u) I'd like to backport this changes to fix crash happens on memory mapped file operations. The patch applies cleanly after 8263361backport.
28-07-2021

no failures in jdk14 atr.
30-01-2020

URL: http://hg.openjdk.java.net/jdk/jdk/rev/3f3dc00a69a5 User: jcm Date: 2019-06-25 19:15:00 +0000
25-06-2019

will push this changeset to jdk 14 eod. http://cr.openjdk.java.net/~jcm/8191278/webrev.06_final/open.changeset
25-06-2019

only unsafe copy implementation that is in cpp is copyswap. as it is very unsafe to predict the generated code for this, the code range will not be gracefully handled.
20-04-2019

implemented fast graceful exit for all platform. except s390(it doesn't implement the unsafe_copy intrinsic) tested aarch64, arm32 bit, x86 32 bit manually , and all other platform in mach5. except ppc.
19-04-2019

with above change test passes in all modes for aarch64.
18-04-2019

probably use same stub implementation arraycopy for native unsafe copy. so that it is one place implementation for all unsafe array copy.
18-04-2019

Note: as per arm docs, unaligned access checks happen before other permission checks(yet to verify in a machine). so skipping faulting instructions for bulk access may cause unaligned faults in arm ports.
02-04-2019

may be something like this for fast exit. http://cr.openjdk.java.net/~jcm/temp/fastfail.00/src/hotspot/os/windows/os_windows.cpp.udiff.html http://cr.openjdk.java.net/~jcm/temp/fastfail.00/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp.udiff.html http://cr.openjdk.java.net/~jcm/temp/fastfail.00/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp.udiff.html
08-03-2019

Compiler side: Improving failover handling may require adding new entry and jumping to that on first (Signal/exception)(Dean suggested this when it was sent last time for review) this may require extensive stub walk to handle all callee save registers properly. Similar changes may be required for non intrinsic case.
05-03-2019

Hi [~hseigel], this implementation works with c2 compiler intrinsic[1] [1] http://cr.openjdk.java.net/~jcm/8191278/webrev.01/
21-02-2019

will do error checking with forced safepoinging in compile exclude code for test case purposes.
14-02-2019

exception don't get delivered to handler even with a forced safepoint in xcomp mode. checking.
13-02-2019

or just check if we are in stub routine and continue. for completeness. the effect of instructions with sideeffects should be studied and taken care. (or else it may loop for ever).
01-02-2019

proposed fix: use same mechanism as runtime, set flag before intrinsic stub call, reset after the call. and use that to handle failure.
30-01-2019

sure, Tobias
29-01-2019

sure, Tobias
29-01-2019

Jamsheed, could you please have a look? Thanks.
23-01-2019

The following webrev fixes the problem for interpreted code and includes a jtreg regression test for both Unsafe_copyMemory() and Unsafe_copySwapMemory(): http://cr.openjdk.java.net/~hseigel/bug_8191278/webrev/index.html When run with the above fix, the test passes on Linux and Mac. It fails on Solaris and WIndows because of errors in the test. The test fails on Solaris because the bogus memory access does not cause a SIGBUS. It fails on Windows because the second File.write() call gets a FileSystemException. When run with '-Xcomp -XX:-TieredCompilation", the test fails everywhere because unsafe_copymemory() is an intrinsic. On Linux, for example, the test fails because when the SIGBUS occurs on Linux x64, control is transferred to this code in JVM_handle_linux_signal(): } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) { // BugId 4454115: A read from a MappedByteBuffer can fault // here if the underlying file has been truncated. // Do not crash the VM in such a case. CodeBlob* cb = CodeCache::find_blob_unsafe(pc); CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; if (nm != NULL && nm->has_unsafe_access()) { address next_pc = Assembler::locate_next_instruction(pc); stub = SharedRuntime::handle_unsafe_access(thread, next_pc); } Unfortunately, "CompiledMethod* nm" gets set to NULL and so handle_unsafe_access() is not executed. Transferring this bug to the compiler team to fix the unsafe_copy_memory() intrinsic issue.
22-01-2019

The single element ops use MemoryAccess to guard the access. This needs to be extended to the bulk operations as well.
19-12-2018

Mikhailo - this is important for java.nio.MappedByteBuffer, the relevant paragraph in the spec starts at "All or part of a mapped byte buffer may become inaccessible ...". Recovery via the handle_unsafe_access stub has been in place since the original implementation (in 1.4) so there is an exception when accessing specific elements of a buffer that is no longer inaccessible but we lack guards for the bulk (copy) operations. This issue is not about direct usages of Unsafe.copyMemory.
18-12-2018

Runtime Triage: Unsafe operations are intentionally not safe. Closing as WNF.
18-12-2018

JDK-8168628 is another example where the underlying issue is that copyMemory is not guarded. We need to get this fixed in HotSpot to avoid this and several reports of crashes with bulk transfer operations (single element put/get are okay as they are guarded).
25-04-2018