diff options
-rw-r--r-- | runtime/aot_class_linker.cc | 6 | ||||
-rw-r--r-- | runtime/aot_class_linker.h | 1 | ||||
-rw-r--r-- | runtime/class_linker.cc | 6 | ||||
-rw-r--r-- | runtime/class_linker.h | 8 | ||||
-rw-r--r-- | runtime/scoped_disable_public_sdk_checker.h | 46 | ||||
-rw-r--r-- | runtime/sdk_checker.cc | 14 | ||||
-rw-r--r-- | runtime/sdk_checker.h | 5 | ||||
-rw-r--r-- | runtime/thread.cc | 11 |
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(); |