Skip to content

Commit 3bcbcc5

Browse files
author
David Holmes
committed
8361439: [BACKOUT] 8357601: Checked version of JNI Release<type>ArrayElements needs to filter out known wrapped arrays
Reviewed-by: lmesnik
1 parent f3e0588 commit 3bcbcc5

File tree

6 files changed

+22
-337
lines changed

6 files changed

+22
-337
lines changed

src/hotspot/os/windows/safefetch_windows.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include "sanitizers/address.hpp"
3030
#include "utilities/globalDefinitions.hpp"
3131

32-
#include <Windows.h>
3332
// On windows, we use structured exception handling to implement SafeFetch
3433

3534
template <class T>

src/hotspot/share/memory/guardedMemory.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@
2525
#include "nmt/memTag.hpp"
2626
#include "runtime/os.hpp"
2727

28-
void* GuardedMemory::wrap_copy(const void* ptr, const size_t len,
29-
const void* tag, const void* tag2) {
28+
void* GuardedMemory::wrap_copy(const void* ptr, const size_t len, const void* tag) {
3029
size_t total_sz = GuardedMemory::get_total_size(len);
3130
void* outerp = os::malloc(total_sz, mtInternal);
3231
if (outerp != nullptr) {
33-
GuardedMemory guarded(outerp, len, tag, tag2);
32+
GuardedMemory guarded(outerp, len, tag);
3433
void* innerp = guarded.get_user_ptr();
3534
if (ptr != nullptr) {
3635
memcpy(innerp, ptr, len);
@@ -59,8 +58,8 @@ void GuardedMemory::print_on(outputStream* st) const {
5958
return;
6059
}
6160
st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT
62-
" tag=" PTR_FORMAT " tag2=" PTR_FORMAT " user_size=%zu user_data=" PTR_FORMAT,
63-
p2i(this), p2i(_base_addr), p2i(get_tag()), p2i(get_tag2()), get_user_size(), p2i(get_user_ptr()));
61+
" tag=" PTR_FORMAT " user_size=%zu user_data=" PTR_FORMAT,
62+
p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr()));
6463

6564
Guard* guard = get_head_guard();
6665
st->print_cr(" Header guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));

src/hotspot/share/memory/guardedMemory.hpp

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
2626
#define SHARE_MEMORY_GUARDEDMEMORY_HPP
2727

2828
#include "memory/allocation.hpp"
29-
#include "runtime/safefetch.hpp"
3029
#include "utilities/globalDefinitions.hpp"
3130

3231
/**
@@ -44,14 +43,13 @@
4443
* |base_addr | 0xABABABABABABABAB | Head guard |
4544
* |+16 | <size_t:user_size> | User data size |
4645
* |+sizeof(uintptr_t) | <tag> | Tag word |
47-
* |+sizeof(uintptr_t) | <tag2> | Tag word |
4846
* |+sizeof(void*) | 0xF1 <user_data> ( | User data |
4947
* |+user_size | 0xABABABABABABABAB | Tail guard |
5048
* -------------------------------------------------------------
5149
*
5250
* Where:
5351
* - guard padding uses "badResourceValue" (0xAB)
54-
* - tag word and tag2 word are general purpose
52+
* - tag word is general purpose
5553
* - user data
5654
* -- initially padded with "uninitBlockPad" (0xF1),
5755
* -- to "freeBlockPad" (0xBA), when freed
@@ -116,11 +114,7 @@ class GuardedMemory : StackObj { // Wrapper on stack
116114
u_char* c = (u_char*) _guard;
117115
u_char* end = c + GUARD_SIZE;
118116
while (c < end) {
119-
// We may not be able to dereference directly so use
120-
// SafeFetch. It doesn't matter if the value read happens
121-
// to be 0xFF as that is not what we expect anyway.
122-
u_char val = (u_char) SafeFetch32((int*)c, 0xFF);
123-
if (val != badResourceValue) {
117+
if (*c != badResourceValue) {
124118
return false;
125119
}
126120
c++;
@@ -143,18 +137,13 @@ class GuardedMemory : StackObj { // Wrapper on stack
143137
size_t _user_size;
144138
};
145139
void* _tag;
146-
void* _tag2;
147140
public:
148141
void set_user_size(const size_t usz) { _user_size = usz; }
149142
size_t get_user_size() const { return _user_size; }
150143

151144
void set_tag(const void* tag) { _tag = (void*) tag; }
152145
void* get_tag() const { return _tag; }
153146

154-
void set_tag2(const void* tag2) { _tag2 = (void*) tag2; }
155-
void* get_tag2() const { return _tag2; }
156-
157-
158147
}; // GuardedMemory::GuardHeader
159148

160149
// Guarded Memory...
@@ -173,11 +162,9 @@ class GuardedMemory : StackObj { // Wrapper on stack
173162
* @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
174163
* @param user_size the size of the user data to be wrapped.
175164
* @param tag optional general purpose tag.
176-
* @param tag2 optional second general purpose tag.
177165
*/
178-
GuardedMemory(void* base_ptr, const size_t user_size,
179-
const void* tag = nullptr, const void* tag2 = nullptr) {
180-
wrap_with_guards(base_ptr, user_size, tag, tag2);
166+
GuardedMemory(void* base_ptr, const size_t user_size, const void* tag = nullptr) {
167+
wrap_with_guards(base_ptr, user_size, tag);
181168
}
182169

183170
/**
@@ -202,19 +189,16 @@ class GuardedMemory : StackObj { // Wrapper on stack
202189
* @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
203190
* @param user_size the size of the user data to be wrapped.
204191
* @param tag optional general purpose tag.
205-
* @param tag2 optional second general purpose tag.
206192
*
207193
* @return user data pointer (inner pointer to supplied "base_ptr").
208194
*/
209-
void* wrap_with_guards(void* base_ptr, size_t user_size,
210-
const void* tag = nullptr, const void* tag2 = nullptr) {
195+
void* wrap_with_guards(void* base_ptr, size_t user_size, const void* tag = nullptr) {
211196
assert(base_ptr != nullptr, "Attempt to wrap null with memory guard");
212197
_base_addr = (u_char*)base_ptr;
213198
get_head_guard()->build();
214199
get_head_guard()->set_user_size(user_size);
215200
get_tail_guard()->build();
216201
set_tag(tag);
217-
set_tag2(tag2);
218202
set_user_bytes(uninitBlockPad);
219203
assert(verify_guards(), "Expected valid memory guards");
220204
return get_user_ptr();
@@ -246,20 +230,6 @@ class GuardedMemory : StackObj { // Wrapper on stack
246230
*/
247231
void* get_tag() const { return get_head_guard()->get_tag(); }
248232

249-
/**
250-
* Set the second general purpose tag.
251-
*
252-
* @param tag general purpose tag.
253-
*/
254-
void set_tag2(const void* tag) { get_head_guard()->set_tag2(tag); }
255-
256-
/**
257-
* Return the second general purpose tag.
258-
*
259-
* @return the second general purpose tag, defaults to null.
260-
*/
261-
void* get_tag2() const { return get_head_guard()->get_tag2(); }
262-
263233
/**
264234
* Return the size of the user data.
265235
*
@@ -332,12 +302,10 @@ class GuardedMemory : StackObj { // Wrapper on stack
332302
* @param ptr the memory to be copied
333303
* @param len the length of the copy
334304
* @param tag optional general purpose tag (see GuardedMemory::get_tag())
335-
* @param tag2 optional general purpose tag (see GuardedMemory::get_tag2())
336305
*
337306
* @return guarded wrapped memory pointer to the user area, or null if OOM.
338307
*/
339-
static void* wrap_copy(const void* p, const size_t len,
340-
const void* tag = nullptr, const void* tag2 = nullptr);
308+
static void* wrap_copy(const void* p, const size_t len, const void* tag = nullptr);
341309

342310
/**
343311
* Free wrapped copy.

src/hotspot/share/prims/jniCheck.cpp

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -350,33 +350,24 @@ check_is_obj_array(JavaThread* thr, jarray jArray) {
350350
}
351351
}
352352

353-
// Arbitrary (but well-known) tag for GetStringChars
354-
const void* STRING_TAG = (void*)0x47114711;
355-
356-
// Arbitrary (but well-known) tag for GetStringUTFChars
357-
const void* STRING_UTF_TAG = (void*) 0x48124812;
358-
359-
// Arbitrary (but well-known) tag for GetPrimitiveArrayCritical
360-
const void* CRITICAL_TAG = (void*)0x49134913;
361-
362353
/*
363354
* Copy and wrap array elements for bounds checking.
364355
* Remember the original elements (GuardedMemory::get_tag())
365356
*/
366357
static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array,
367-
void* orig_elements, jboolean is_critical = JNI_FALSE) {
358+
void* orig_elements) {
368359
void* result;
369360
IN_VM(
370361
oop a = JNIHandles::resolve_non_null(array);
371362
size_t len = arrayOop(a)->length() <<
372363
TypeArrayKlass::cast(a->klass())->log2_element_size();
373-
result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements, is_critical ? CRITICAL_TAG : nullptr);
364+
result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements);
374365
)
375366
return result;
376367
}
377368

378369
static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
379-
void* obj, void* carray, size_t* rsz, jboolean is_critical) {
370+
void* obj, void* carray, size_t* rsz) {
380371
if (carray == nullptr) {
381372
tty->print_cr("%s: elements vector null" PTR_FORMAT, fn_name, p2i(obj));
382373
NativeReportJNIFatalError(thr, "Elements vector null");
@@ -395,29 +386,6 @@ static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
395386
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
396387
NativeReportJNIFatalError(thr, err_msg("%s: unrecognized elements", fn_name));
397388
}
398-
if (orig_result == STRING_TAG || orig_result == STRING_UTF_TAG) {
399-
bool was_utf = orig_result == STRING_UTF_TAG;
400-
tty->print_cr("%s: called on something allocated by %s",
401-
fn_name, was_utf ? "GetStringUTFChars" : "GetStringChars");
402-
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
403-
NativeReportJNIFatalError(thr, err_msg("%s called on something allocated by %s",
404-
fn_name, was_utf ? "GetStringUTFChars" : "GetStringChars"));
405-
}
406-
407-
if (is_critical && (guarded.get_tag2() != CRITICAL_TAG)) {
408-
tty->print_cr("%s: called on something not allocated by GetPrimitiveArrayCritical", fn_name);
409-
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
410-
NativeReportJNIFatalError(thr, err_msg("%s called on something not allocated by GetPrimitiveArrayCritical",
411-
fn_name));
412-
}
413-
414-
if (!is_critical && (guarded.get_tag2() == CRITICAL_TAG)) {
415-
tty->print_cr("%s: called on something allocated by GetPrimitiveArrayCritical", fn_name);
416-
DEBUG_ONLY(guarded.print_on(tty);) // This may crash.
417-
NativeReportJNIFatalError(thr, err_msg("%s called on something allocated by GetPrimitiveArrayCritical",
418-
fn_name));
419-
}
420-
421389
if (rsz != nullptr) {
422390
*rsz = guarded.get_user_size();
423391
}
@@ -427,7 +395,7 @@ static void* check_wrapped_array(JavaThread* thr, const char* fn_name,
427395
static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name,
428396
void* obj, void* carray, jint mode, jboolean is_critical) {
429397
size_t sz;
430-
void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz, is_critical);
398+
void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz);
431399
switch (mode) {
432400
case 0:
433401
memcpy(orig_result, carray, sz);
@@ -1462,6 +1430,9 @@ JNI_ENTRY_CHECKED(jsize,
14621430
return result;
14631431
JNI_END
14641432

1433+
// Arbitrary (but well-known) tag
1434+
const void* STRING_TAG = (void*)0x47114711;
1435+
14651436
JNI_ENTRY_CHECKED(const jchar *,
14661437
checked_jni_GetStringChars(JNIEnv *env,
14671438
jstring str,
@@ -1564,6 +1535,9 @@ JNI_ENTRY_CHECKED(jlong,
15641535
return result;
15651536
JNI_END
15661537

1538+
// Arbitrary (but well-known) tag - different than GetStringChars
1539+
const void* STRING_UTF_TAG = (void*) 0x48124812;
1540+
15671541
JNI_ENTRY_CHECKED(const char *,
15681542
checked_jni_GetStringUTFChars(JNIEnv *env,
15691543
jstring str,
@@ -1885,7 +1859,7 @@ JNI_ENTRY_CHECKED(void *,
18851859
)
18861860
void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy);
18871861
if (result != nullptr) {
1888-
result = check_jni_wrap_copy_array(thr, array, result, JNI_TRUE);
1862+
result = check_jni_wrap_copy_array(thr, array, result);
18891863
}
18901864
functionExit(thr);
18911865
return result;

0 commit comments

Comments
 (0)