From ce4b257fa539d35a7d14bba2d5d3342093d714e1 Mon Sep 17 00:00:00 2001 From: Jorn Vernee Date: Mon, 11 Dec 2023 19:05:40 +0000 Subject: [PATCH] 8320886: Unsafe_SetMemory0 is not guarded Reviewed-by: dholmes, fparain --- src/hotspot/cpu/x86/assembler_x86.cpp | 3 ++- src/hotspot/share/prims/unsafe.cpp | 5 +++- .../runtime/Unsafe/InternalErrorTest.java | 24 ++++++++++++------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index cedddaed975..8a2b3aa0436 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -920,6 +920,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x11: // movups case 0x12: // movlps case 0x28: // movaps + case 0x29: // movaps case 0x2E: // ucomiss case 0x2F: // comiss case 0x54: // andps @@ -969,7 +970,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { assert(which == call32_operand, "jcc has no disp32 or imm"); return ip; default: - ShouldNotReachHere(); + fatal("not handled: 0x0F%2X", 0xFF & *(ip-1)); } break; diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp index ece60d32f9a..1a05c0fa13e 100644 --- a/src/hotspot/share/prims/unsafe.cpp +++ b/src/hotspot/share/prims/unsafe.cpp @@ -390,7 +390,10 @@ UNSAFE_ENTRY_SCOPED(void, Unsafe_SetMemory0(JNIEnv *env, jobject unsafe, jobject oop base = JNIHandles::resolve(obj); void* p = index_oop_from_field_offset_long(base, offset); - Copy::fill_to_memory_atomic(p, sz, value); + { + GuardUnsafeAccess guard(thread); + Copy::fill_to_memory_atomic(p, sz, value); + } } UNSAFE_END UNSAFE_ENTRY_SCOPED(void, Unsafe_CopyMemory0(JNIEnv *env, jobject unsafe, jobject srcObj, jlong srcOffset, jobject dstObj, jlong dstOffset, jlong size)) { diff --git a/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java b/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java index 57599cffd62..fcf48a7a2d7 100644 --- a/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java +++ b/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java @@ -41,6 +41,7 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.lang.foreign.MemorySegment; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.MappedByteBuffer; @@ -60,6 +61,8 @@ public class InternalErrorTest { private static final String failureMsg1 = "InternalError not thrown"; private static final String failureMsg2 = "Wrong InternalError: "; + private static final int NUM_TESTS = 4; + public static void main(String[] args) throws Throwable { Unsafe unsafe = Unsafe.getUnsafe(); @@ -71,9 +74,9 @@ public class InternalErrorTest { s.append("1"); } Files.write(file.toPath(), s.toString().getBytes()); - FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel(); + FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel(); MappedByteBuffer buffer = - fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size()); + fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileChannel.size()); // Get address of mapped memory. long mapAddr = 0; @@ -86,13 +89,13 @@ public class InternalErrorTest { } long allocMem = unsafe.allocateMemory(4000); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < NUM_TESTS; i++) { test(buffer, unsafe, mapAddr, allocMem, i); } Files.write(file.toPath(), "2".getBytes()); buffer.position(buffer.position() + pageSize); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < NUM_TESTS; i++) { try { test(buffer, unsafe, mapAddr, allocMem, i); WhiteBox.getWhiteBox().forceSafepoint(); @@ -107,7 +110,7 @@ public class InternalErrorTest { Method m = InternalErrorTest.class.getMethod("test", MappedByteBuffer.class, Unsafe.class, long.class, long.class, int.class); WhiteBox.getWhiteBox().enqueueMethodForCompilation(m, 3); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < NUM_TESTS; i++) { try { test(buffer, unsafe, mapAddr, allocMem, i); WhiteBox.getWhiteBox().forceSafepoint(); @@ -121,7 +124,7 @@ public class InternalErrorTest { WhiteBox.getWhiteBox().enqueueMethodForCompilation(m, 4); - for (int i = 0; i < 3; i++) { + for (int i = 0; i < NUM_TESTS; i++) { try { test(buffer, unsafe, mapAddr, allocMem, i); WhiteBox.getWhiteBox().forceSafepoint(); @@ -143,13 +146,18 @@ public class InternalErrorTest { buffer.get(new byte[8]); break; case 1: - // testing Unsafe.copySwapMemory, trying to access next page after truncation. + // testing Unsafe.copySwapMemory, trying to access next page after truncation. unsafe.copySwapMemory(null, mapAddr + pageSize, new byte[4000], 16, 2000, 2); break; case 2: - // testing Unsafe.copySwapMemory, trying to access next page after truncation. + // testing Unsafe.copySwapMemory, trying to access next page after truncation. unsafe.copySwapMemory(null, mapAddr + pageSize, null, allocMem, 2000, 2); break; + case 3: + MemorySegment segment = MemorySegment.ofBuffer(buffer); + // testing Unsafe.setMemory, trying to access next page after truncation. + segment.fill((byte) 0xF0); + break; } }