summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/aot_class_linker.cc6
-rw-r--r--runtime/aot_class_linker.h1
-rw-r--r--runtime/class_linker.cc6
-rw-r--r--runtime/class_linker.h8
-rw-r--r--runtime/scoped_disable_public_sdk_checker.h46
-rw-r--r--runtime/sdk_checker.cc14
-rw-r--r--runtime/sdk_checker.h5
-rw-r--r--runtime/thread.cc11
8 files changed, 93 insertions, 4 deletions
diff --git a/runtime/aot_class_linker.cc b/runtime/aot_class_linker.cc
index b11c08d4e5..505946646d 100644
--- a/runtime/aot_class_linker.cc
+++ b/runtime/aot_class_linker.cc
@@ -262,4 +262,10 @@ bool AotClassLinker::DenyAccessBasedOnPublicSdk(const char* type_descriptor) con
return sdk_checker_ != nullptr && sdk_checker_->ShouldDenyAccess(type_descriptor);
}
+void AotClassLinker::SetEnablePublicSdkChecks(bool enabled) {
+ if (sdk_checker_ != nullptr) {
+ sdk_checker_->SetEnabled(enabled);
+ }
+}
+
} // namespace art
diff --git a/runtime/aot_class_linker.h b/runtime/aot_class_linker.h
index 30a79aa489..a094e3a174 100644
--- a/runtime/aot_class_linker.h
+++ b/runtime/aot_class_linker.h
@@ -46,6 +46,7 @@ static bool CanReferenceInBootImageExtension(ObjPtr<mirror::Class> klass, gc::He
bool DenyAccessBasedOnPublicSdk(ArtField* art_field ATTRIBUTE_UNUSED) const override
REQUIRES_SHARED(Locks::mutator_lock_);
bool DenyAccessBasedOnPublicSdk(const char* type_descriptor ATTRIBUTE_UNUSED) const override;
+ void SetEnablePublicSdkChecks(bool enabled) override;
protected:
// Overridden version of PerformClassVerification allows skipping verification if the class was
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 8982368af4..f396a0a84a 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -9920,6 +9920,12 @@ bool ClassLinker::DenyAccessBasedOnPublicSdk(const char* type_descriptor ATTRIBU
UNREACHABLE();
}
+void ClassLinker::SetEnablePublicSdkChecks(bool enabled ATTRIBUTE_UNUSED) {
+ // Should not be called on ClassLinker, only on AotClassLinker that overrides this.
+ LOG(FATAL) << "UNREACHABLE";
+ UNREACHABLE();
+}
+
// Instantiate ClassLinker::ResolveMethod.
template ArtMethod* ClassLinker::ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
uint32_t method_idx,
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 94d19995c1..050b02a42f 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -825,13 +825,15 @@ class ClassLinker {
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
// Verifies if the method is accesible according to the SdkChecker (if installed).
- virtual bool DenyAccessBasedOnPublicSdk(ArtMethod* art_method ATTRIBUTE_UNUSED) const
+ virtual bool DenyAccessBasedOnPublicSdk(ArtMethod* art_method) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Verifies if the field is accesible according to the SdkChecker (if installed).
- virtual bool DenyAccessBasedOnPublicSdk(ArtField* art_field ATTRIBUTE_UNUSED) const
+ virtual bool DenyAccessBasedOnPublicSdk(ArtField* art_field) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Verifies if the descriptor is accesible according to the SdkChecker (if installed).
- virtual bool DenyAccessBasedOnPublicSdk(const char* type_descriptor ATTRIBUTE_UNUSED) const;
+ virtual bool DenyAccessBasedOnPublicSdk(const char* type_descriptor) const;
+ // Enable or disable public sdk checks.
+ virtual void SetEnablePublicSdkChecks(bool enabled);
protected:
virtual bool InitializeClass(Thread* self,
diff --git a/runtime/scoped_disable_public_sdk_checker.h b/runtime/scoped_disable_public_sdk_checker.h
new file mode 100644
index 0000000000..4ec1af3fa4
--- /dev/null
+++ b/runtime/scoped_disable_public_sdk_checker.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_SCOPED_DISABLE_PUBLIC_SDK_CHECKER_H_
+#define ART_RUNTIME_SCOPED_DISABLE_PUBLIC_SDK_CHECKER_H_
+
+#include "class_linker.h"
+
+namespace art {
+
+// Utility class to disabled the public sdk checker within a scope (if installed).
+class ScopedDisablePublicSdkChecker : public ValueObject {
+ public:
+ ALWAYS_INLINE ScopedDisablePublicSdkChecker() {
+ Runtime* runtime = Runtime::Current();
+ if (UNLIKELY(runtime->IsAotCompiler())) {
+ runtime->GetClassLinker()->SetEnablePublicSdkChecks(false);
+ }
+ }
+
+ ALWAYS_INLINE ~ScopedDisablePublicSdkChecker() {
+ Runtime* runtime = Runtime::Current();
+ if (UNLIKELY(runtime->IsAotCompiler())) {
+ runtime->GetClassLinker()->SetEnablePublicSdkChecks(true);
+ }
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedDisablePublicSdkChecker);
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_SCOPED_DISABLE_PUBLIC_SDK_CHECKER_H_
diff --git a/runtime/sdk_checker.cc b/runtime/sdk_checker.cc
index 22c43058e4..1dbe39c32e 100644
--- a/runtime/sdk_checker.cc
+++ b/runtime/sdk_checker.cc
@@ -23,7 +23,7 @@
namespace art {
-SdkChecker::SdkChecker() {}
+SdkChecker::SdkChecker() : enabled_(true) {}
SdkChecker* SdkChecker::Create(
const std::string& public_sdk, std::string* error_msg) {
@@ -47,6 +47,10 @@ SdkChecker* SdkChecker::Create(
}
bool SdkChecker::ShouldDenyAccess(ArtMethod* art_method) const {
+ if (!enabled_) {
+ return false;
+ }
+
bool found = false;
for (const std::unique_ptr<const DexFile>& dex_file : sdk_dex_files_) {
const dex::TypeId* declaring_type_id =
@@ -89,6 +93,10 @@ bool SdkChecker::ShouldDenyAccess(ArtMethod* art_method) const {
}
bool SdkChecker::ShouldDenyAccess(ArtField* art_field) const {
+ if (!enabled_) {
+ return false;
+ }
+
bool found = false;
for (const std::unique_ptr<const DexFile>& dex_file : sdk_dex_files_) {
std::string declaring_class;
@@ -123,6 +131,10 @@ bool SdkChecker::ShouldDenyAccess(ArtField* art_field) const {
}
bool SdkChecker::ShouldDenyAccess(const char* descriptor) const {
+ if (!enabled_) {
+ return false;
+ }
+
bool found = false;
for (const std::unique_ptr<const DexFile>& dex_file : sdk_dex_files_) {
const dex::TypeId* type_id = dex_file->FindTypeId(descriptor);
diff --git a/runtime/sdk_checker.h b/runtime/sdk_checker.h
index 29cb98d538..8d82237a60 100644
--- a/runtime/sdk_checker.h
+++ b/runtime/sdk_checker.h
@@ -60,10 +60,15 @@ class SdkChecker {
// Similar to ShouldDenyAccess(ArtMethod* art_method).
bool ShouldDenyAccess(const char* type_descriptor) const;
+ // Enabled/Disable the checks.
+ void SetEnabled(bool enabled) { enabled_ = enabled; }
+
private:
SdkChecker();
std::vector<std::unique_ptr<const DexFile>> sdk_dex_files_;
+
+ bool enabled_;
};
} // namespace art
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 645c51f73b..7f80691e54 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -104,6 +104,7 @@
#include "runtime.h"
#include "runtime_callbacks.h"
#include "scoped_thread_state_change-inl.h"
+#include "scoped_disable_public_sdk_checker.h"
#include "stack.h"
#include "stack_map.h"
#include "thread-inl.h"
@@ -3190,6 +3191,16 @@ void Thread::ThrowNewWrappedException(const char* exception_class_descriptor,
DCHECK_EQ(this, Thread::Current());
ScopedObjectAccessUnchecked soa(this);
StackHandleScope<3> hs(soa.Self());
+
+ // Disable public sdk checks if we need to throw exceptions.
+ // The checks are only used in AOT compilation and may block (exception) class
+ // initialization if it needs access to private fields (e.g. serialVersionUID).
+ //
+ // Since throwing an exception will EnsureInitialization and the public sdk may
+ // block that, disable the checks. It's ok to do so, because the thrown exceptions
+ // are not part of the application code that needs to verified.
+ ScopedDisablePublicSdkChecker sdpsc;
+
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetCurrentClassLoader(soa.Self())));
ScopedLocalRef<jobject> cause(GetJniEnv(), soa.AddLocalReference<jobject>(GetException()));
ClearException();