8297877: Risk for uninitialized memory in case of CHECK macro early return as part of field access

Reviewed-by: ccheung, egahlin
This commit is contained in:
Markus Grönlund 2023-01-13 12:11:09 +00:00
parent be8e6d05db
commit ac63f5f8dd
3 changed files with 32 additions and 34 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -418,6 +418,8 @@ static void lookup_field(JfrJavaArguments* args, const InstanceKlass* ik, fieldD
}
static void read_field(JfrJavaArguments* args, JavaValue* result, Thread* thread) {
assert(result != nullptr, "invariant");
assert(result->get_oop() == nullptr, "result not initialized");
const bool static_field = !args->has_receiver();
fieldDescriptor fd;
const InstanceKlass* const ik = static_cast<InstanceKlass*>(args->klass());
@ -432,14 +434,14 @@ static void read_field(JfrJavaArguments* args, JavaValue* result, TRAPS) {
assert(args != NULL, "invariant");
assert(result != NULL, "invariant");
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
result->set_oop(nullptr); // Initialize result in case klass initialize throws.
InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass());
klass->initialize(CHECK);
read_field(args, result, static_cast<Thread*>(THREAD));
}
static void write_field(JfrJavaArguments* args, JavaValue* result, TRAPS) {
static void write_field(JfrJavaArguments* args, TRAPS) {
assert(args != NULL, "invariant");
assert(result != NULL, "invariant");
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
InstanceKlass* const klass = static_cast<InstanceKlass*>(args->klass());
@ -457,7 +459,7 @@ static void write_field(JfrJavaArguments* args, JavaValue* result, TRAPS) {
void JfrJavaSupport::set_field(JfrJavaArguments* args, TRAPS) {
assert(args != NULL, "invariant");
write_field(args, args->result(), THREAD);
write_field(args, THREAD);
}
void JfrJavaSupport::get_field(JfrJavaArguments* args, TRAPS) {
@ -465,39 +467,30 @@ void JfrJavaSupport::get_field(JfrJavaArguments* args, TRAPS) {
read_field(args, args->result(), THREAD);
}
void JfrJavaSupport::get_field(JfrJavaArguments* args, Thread* thread) {
static void get_field_ref(JfrJavaArguments* args, bool local_ref, TRAPS) {
assert(args != NULL, "invariant");
read_field(args, args->result(), thread);
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
JavaValue* const result = args->result();
assert(result != NULL, "invariant");
assert(result->get_type() == T_OBJECT, "invariant");
read_field(args, result, CHECK);
const oop obj = result->get_oop();
if (obj == nullptr) {
return;
}
if (local_ref) {
result->set_jobject(JfrJavaSupport::local_jni_handle(obj, THREAD));
} else {
result->set_jobject(JfrJavaSupport::global_jni_handle(obj, THREAD));
}
}
void JfrJavaSupport::get_field_local_ref(JfrJavaArguments* args, TRAPS) {
assert(args != NULL, "invariant");
DEBUG_ONLY(check_java_thread_in_vm(THREAD));
JavaValue* const result = args->result();
assert(result != NULL, "invariant");
assert(result->get_type() == T_OBJECT, "invariant");
read_field(args, result, CHECK);
const oop obj = result->get_oop();
if (obj != NULL) {
result->set_jobject(local_jni_handle(obj, THREAD));
}
get_field_ref(args, true /* local_ref */, THREAD);
}
void JfrJavaSupport::get_field_global_ref(JfrJavaArguments* args, TRAPS) {
assert(args != NULL, "invariant");
DEBUG_ONLY(check_java_thread_in_vm(THREAD));
JavaValue* const result = args->result();
assert(result != NULL, "invariant");
assert(result->get_type() == T_OBJECT, "invariant");
read_field(args, result, CHECK);
const oop obj = result->get_oop();
if (obj != NULL) {
result->set_jobject(global_jni_handle(obj, THREAD));
}
get_field_ref(args, false /* local_ref */, THREAD);
}
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -57,7 +57,6 @@ class JfrJavaSupport : public AllStatic {
static void set_field(JfrJavaArguments* args, TRAPS);
static void get_field(JfrJavaArguments* args, TRAPS);
static void get_field(JfrJavaArguments* args, Thread* thread);
static void new_object(JfrJavaArguments* args, TRAPS);
// global jni handle result

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
#include "jfr/jni/jfrJavaSupport.hpp"
#include "jfr/recorder/repository/jfrChunkRotation.hpp"
#include "jfr/recorder/repository/jfrChunkWriter.hpp"
#include "logging/log.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
@ -56,7 +57,12 @@ static void notify() {
JavaThread* const thread = JavaThread::current();
// can safepoint here
ThreadInVMfromNative transition(thread);
JfrJavaSupport::notify_all(get_chunk_monitor(thread), thread);
jobject monitor = get_chunk_monitor(thread);
if (monitor == nullptr) {
log_error(jfr, system)("Unable to create chunk rotation monitor");
return;
}
JfrJavaSupport::notify_all(monitor, thread);
}
void JfrChunkRotation::evaluate(const JfrChunkWriter& writer) {