diff options
Diffstat (limited to 'runtime/jni_internal.cc')
-rw-r--r-- | runtime/jni_internal.cc | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index b8e6ebe8d8..c40360f612 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -34,6 +34,7 @@ #include "class_linker-inl.h" #include "dex/dex_file-inl.h" #include "fault_handler.h" +#include "hidden_api.h" #include "gc/accounting/card_table-inl.h" #include "gc_root.h" #include "indirect_reference_table-inl.h" @@ -79,15 +80,17 @@ namespace art { // things not rendering correctly. E.g. b/16858794 static constexpr bool kWarnJniAbort = false; -// Helpers to call instrumentation functions for fields. These take jobjects so we don't need to set -// up handles for the rare case where these actually do something. Once these functions return it is -// possible there will be a pending exception if the instrumentation happens to throw one. +// Helpers to check if we need to warn about accessing hidden API fields and to call instrumentation +// functions for them. These take jobjects so we don't need to set up handles for the rare case +// where these actually do something. Once these functions return it is possible there will be +// a pending exception if the instrumentation happens to throw one. static void NotifySetObjectField(ArtField* field, jobject obj, jobject jval) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK_EQ(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot); + Thread* self = Thread::Current(); + hiddenapi::MaybeWarnAboutMemberAccess(field, self, /* num_frames */ 1); instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (UNLIKELY(instrumentation->HasFieldWriteListeners())) { - Thread* self = Thread::Current(); ArtMethod* cur_method = self->GetCurrentMethod(/*dex_pc*/ nullptr, /*check_suspended*/ true, /*abort_on_error*/ false); @@ -112,9 +115,10 @@ static void NotifySetObjectField(ArtField* field, jobject obj, jobject jval) static void NotifySetPrimitiveField(ArtField* field, jobject obj, JValue val) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot); + Thread* self = Thread::Current(); + hiddenapi::MaybeWarnAboutMemberAccess(field, self, /* num_frames */ 1); instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (UNLIKELY(instrumentation->HasFieldWriteListeners())) { - Thread* self = Thread::Current(); ArtMethod* cur_method = self->GetCurrentMethod(/*dex_pc*/ nullptr, /*check_suspended*/ true, /*abort_on_error*/ false); @@ -136,9 +140,10 @@ static void NotifySetPrimitiveField(ArtField* field, jobject obj, JValue val) static void NotifyGetField(ArtField* field, jobject obj) REQUIRES_SHARED(Locks::mutator_lock_) { + Thread* self = Thread::Current(); + hiddenapi::MaybeWarnAboutMemberAccess(field, self, /* num_frames */ 1); instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (UNLIKELY(instrumentation->HasFieldReadListeners())) { - Thread* self = Thread::Current(); ArtMethod* cur_method = self->GetCurrentMethod(/*dex_pc*/ nullptr, /*check_suspended*/ true, /*abort_on_error*/ false); @@ -238,6 +243,10 @@ static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class, } else { method = c->FindClassMethod(name, sig, pointer_size); } + if (method != nullptr && + hiddenapi::ShouldBlockAccessToMember(method, soa.Self(), /* num_frames */ 1)) { + method = nullptr; + } if (method == nullptr || method->IsStatic() != is_static) { ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static"); return nullptr; @@ -314,6 +323,10 @@ static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, con } else { field = c->FindInstanceField(name, field_type->GetDescriptor(&temp)); } + if (field != nullptr && + hiddenapi::ShouldBlockAccessToMember(field, soa.Self(), /* num_frames */ 1)) { + field = nullptr; + } if (field == nullptr) { soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", "no \"%s\" field \"%s\" in class \"%s\" or its superclasses", |