diff options
23 files changed, 67 insertions, 1296 deletions
diff --git a/runtime/hidden_api_jni.cc b/runtime/hidden_api_jni.cc index 2e3222449c..074c4c3a76 100644 --- a/runtime/hidden_api_jni.cc +++ b/runtime/hidden_api_jni.cc @@ -25,7 +25,6 @@ #include <mutex> #include "android-base/logging.h" -#include "android-base/thread_annotations.h" #include "unwindstack/Regs.h" #include "unwindstack/RegsGetLocal.h" @@ -46,7 +45,7 @@ namespace { // The maximum number of frames to back trace through when performing Core Platform API checks of // native code. -static constexpr size_t kMaxFramesForHiddenApiJniCheck = 3; +static constexpr size_t kMaxFrames = 3; static std::mutex gUnwindingMutex; @@ -74,16 +73,25 @@ struct UnwindHelper { }; static UnwindHelper& GetUnwindHelper() { - static UnwindHelper helper(kMaxFramesForHiddenApiJniCheck); + static UnwindHelper helper(kMaxFrames); return helper; } } // namespace +enum class SharedObjectKind { + kRuntime = 0, + kApexModule = 1, + kOther = 2 +}; + std::ostream& operator<<(std::ostream& os, SharedObjectKind kind) { switch (kind) { - case SharedObjectKind::kArtModule: - os << "ART module"; + case SharedObjectKind::kRuntime: + os << "Runtime"; + break; + case SharedObjectKind::kApexModule: + os << "APEX Module"; break; case SharedObjectKind::kOther: os << "Other"; @@ -110,9 +118,12 @@ class CodeRangeCache final { return SharedObjectKind::kOther; } + bool HasCache() const { + return memory_type_table_.Size() != 0; + } + void BuildCache() { - std::lock_guard<std::mutex> guard(mutex_); - DCHECK_EQ(memory_type_table_.Size(), 0u); + DCHECK(!HasCache()); art::MemoryTypeTable<SharedObjectKind>::Builder builder; builder_ = &builder; libjavacore_loaded_ = false; @@ -130,18 +141,7 @@ class CodeRangeCache final { builder_ = nullptr; } - void SetLibraryPathClassifier(JniLibraryPathClassifier* fc_classifier) { - std::lock_guard<std::mutex> guard(mutex_); - fc_classifier_ = fc_classifier; - } - - bool HasLibraryPathClassifier() const { - std::lock_guard<std::mutex> guard(mutex_); - return fc_classifier_ != nullptr; - } - void DropCache() { - const std::lock_guard<std::mutex> guard(mutex_); memory_type_table_ = {}; } @@ -149,7 +149,6 @@ class CodeRangeCache final { CodeRangeCache() {} bool Find(uintptr_t address, SharedObjectKind* kind) const { - std::lock_guard<std::mutex> guard(mutex_); const art::MemoryTypeRange<SharedObjectKind>* range = memory_type_table_.Lookup(address); if (range == nullptr) { return false; @@ -170,14 +169,7 @@ class CodeRangeCache final { } uintptr_t start = info->dlpi_addr + phdr.p_vaddr; const uintptr_t limit = art::RoundUp(start + phdr.p_memsz, art::kPageSize); - SharedObjectKind kind = GetKind(info->dlpi_name); - if (cache->fc_classifier_ != nullptr) { - std::optional<SharedObjectKind> maybe_kind = - cache->fc_classifier_->Classify(info->dlpi_name); - if (maybe_kind.has_value()) { - kind = maybe_kind.value(); - } - } + SharedObjectKind kind = GetKind(info->dlpi_name, start, limit); art::MemoryTypeRange<SharedObjectKind> range{start, limit, kind}; if (!builder->Add(range)) { LOG(WARNING) << "Overlapping/invalid range found in ELF headers: " << range; @@ -199,29 +191,25 @@ class CodeRangeCache final { return 0; } - static SharedObjectKind GetKind(const char* so_name) { - return art::LocationIsOnArtModule(so_name) ? SharedObjectKind::kArtModule - : SharedObjectKind::kOther; + static SharedObjectKind GetKind(const char* so_name, uintptr_t start, uintptr_t limit) { + uintptr_t runtime_method = reinterpret_cast<uintptr_t>(CodeRangeCache::GetKind); + if (runtime_method >= start && runtime_method < limit) { + return SharedObjectKind::kRuntime; + } + return art::LocationIsOnApex(so_name) ? SharedObjectKind::kApexModule + : SharedObjectKind::kOther; } - // Table builder, only valid during BuildCache(). - art::MemoryTypeTable<SharedObjectKind>::Builder* builder_ GUARDED_BY(mutex_) = nullptr; - - // Table for mapping PC addresses to their shared object files. - art::MemoryTypeTable<SharedObjectKind> memory_type_table_ GUARDED_BY(mutex_); + art::MemoryTypeTable<SharedObjectKind> memory_type_table_; - // Classifier used to override shared object classifications during tests. - JniLibraryPathClassifier* fc_classifier_ GUARDED_BY(mutex_) = nullptr; + // Table builder, only valid during BuildCache(). + art::MemoryTypeTable<SharedObjectKind>::Builder* builder_; // Sanity checking state. bool libjavacore_loaded_; bool libnativehelper_loaded_; bool libopenjdk_loaded_; - // Mutex to protect fc_classifier_ and related state during testing. Outside of testing we - // only generate the |memory_type_table_| once. - mutable std::mutex mutex_; - static constexpr std::string_view kLibjavacore = "libjavacore.so"; static constexpr std::string_view kLibnativehelper = "libnativehelper.so"; static constexpr std::string_view kLibopenjdk = art::kIsDebugBuild ? "libopenjdkd.so" @@ -243,39 +231,21 @@ ScopedCorePlatformApiCheck::ScopedCorePlatformApiCheck() { CorePlatformApiCookie cookie = bit_cast<CorePlatformApiCookie, uint32_t>(self->CorePlatformApiCookie()); bool is_core_platform_api_approved = false; // Default value for non-device testing. - const bool is_under_test = CodeRangeCache::GetSingleton().HasLibraryPathClassifier(); - if (kIsTargetBuild || is_under_test) { - // On target device (or running tests). If policy says enforcement is disabled, - // then treat all callers as approved. + if (!kIsTargetBuild) { + // On target device, if policy says enforcement is disabled, then treat all callers as + // approved. auto policy = Runtime::Current()->GetCorePlatformApiEnforcementPolicy(); if (policy == hiddenapi::EnforcementPolicy::kDisabled) { is_core_platform_api_approved = true; } else if (cookie.depth == 0) { - // On target device, only check the caller at depth 0 which corresponds to the outermost - // entry into the JNI interface. When performing the check here, we note that |*this| is - // stack allocated at entry points to JNI field and method resolution |*methods. We can use - // the address of |this| to find the callers frame. + // On target device, only check the caller at depth 0 (the outermost entry into JNI + // interface). DCHECK_EQ(cookie.approved, false); - void* caller_pc = nullptr; - { - std::lock_guard<std::mutex> guard(gUnwindingMutex); - unwindstack::Unwinder* unwinder = GetUnwindHelper().Unwinder(); - std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal()); - RegsGetLocal(regs.get()); - unwinder->SetRegs(regs.get()); - unwinder->Unwind(); - for (auto it = unwinder->frames().begin(); it != unwinder->frames().end(); ++it) { - // Unwind to frame above the tlsJniStackMarker. The stack markers should be on the first - // frame calling JNI methods. - if (it->sp > reinterpret_cast<uint64_t>(this)) { - caller_pc = reinterpret_cast<void*>(it->pc); - break; - } - } - } + void* caller_pc = CaptureCallerPc(); if (caller_pc != nullptr) { SharedObjectKind kind = CodeRangeCache::GetSingleton().GetSharedObjectKind(caller_pc); - is_core_platform_api_approved = (kind == SharedObjectKind::kArtModule); + is_core_platform_api_approved = ((kind == SharedObjectKind::kRuntime) || + (kind == SharedObjectKind::kApexModule)); } } } @@ -309,15 +279,30 @@ bool ScopedCorePlatformApiCheck::IsCurrentCallerApproved(Thread* self) { return cookie.approved; } -void JniInitializeNativeCallerCheck(JniLibraryPathClassifier* classifier) { +void* ScopedCorePlatformApiCheck::CaptureCallerPc() { + std::lock_guard<std::mutex> guard(gUnwindingMutex); + unwindstack::Unwinder* unwinder = GetUnwindHelper().Unwinder(); + std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal()); + RegsGetLocal(regs.get()); + unwinder->SetRegs(regs.get()); + unwinder->Unwind(); + for (auto it = unwinder->frames().begin(); it != unwinder->frames().end(); ++it) { + // Unwind to frame above the tlsJniStackMarker. The stack markers should be on the first frame + // calling JNI methods. + if (it->sp > reinterpret_cast<uint64_t>(this)) { + return reinterpret_cast<void*>(it->pc); + } + } + return nullptr; +} + +void JniInitializeNativeCallerCheck() { // This method should be called only once and before there are multiple runtime threads. - CodeRangeCache::GetSingleton().DropCache(); - CodeRangeCache::GetSingleton().SetLibraryPathClassifier(classifier); + DCHECK(!CodeRangeCache::GetSingleton().HasCache()); CodeRangeCache::GetSingleton().BuildCache(); } void JniShutdownNativeCallerCheck() { - CodeRangeCache::GetSingleton().SetLibraryPathClassifier(nullptr); CodeRangeCache::GetSingleton().DropCache(); } @@ -337,7 +322,7 @@ bool ScopedCorePlatformApiCheck::IsCurrentCallerApproved(Thread* self ATTRIBUTE_ return false; } -void JniInitializeNativeCallerCheck(JniLibraryPathClassifier* f ATTRIBUTE_UNUSED) {} +void JniInitializeNativeCallerCheck() {} void JniShutdownNativeCallerCheck() {} diff --git a/runtime/hidden_api_jni.h b/runtime/hidden_api_jni.h index 15de6effab..a084378406 100644 --- a/runtime/hidden_api_jni.h +++ b/runtime/hidden_api_jni.h @@ -17,8 +17,6 @@ #ifndef ART_RUNTIME_HIDDEN_API_JNI_H_ #define ART_RUNTIME_HIDDEN_API_JNI_H_ -#include <optional> - #include "base/macros.h" namespace art { @@ -39,25 +37,16 @@ class ScopedCorePlatformApiCheck final { static bool IsCurrentCallerApproved(Thread* self); private: + // Captures calling PC for frame above the frame allocating the current ScopedCorePlatformApiCheck + // instance. + void* CaptureCallerPc(); + // Instances should only be stack allocated, copy and assignment not useful. DISALLOW_ALLOCATION(); DISALLOW_COPY_AND_ASSIGN(ScopedCorePlatformApiCheck); }; -// Kind of memory page from mapped shared object files. -enum class SharedObjectKind { - kArtModule = 0, // Part of the ART module. - kOther = 1 // Neither of the above. -}; - - -class JniLibraryPathClassifier { - public: - virtual std::optional<SharedObjectKind> Classify(const char* so_name) = 0; - virtual ~JniLibraryPathClassifier() {} -}; - -void JniInitializeNativeCallerCheck(JniLibraryPathClassifier* fc = nullptr); +void JniInitializeNativeCallerCheck(); void JniShutdownNativeCallerCheck(); } // namespace hiddenapi diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc index 887ad9a172..882e10f12d 100644 --- a/runtime/jni/jni_internal.cc +++ b/runtime/jni/jni_internal.cc @@ -88,17 +88,9 @@ static constexpr bool kWarnJniAbort = false; template<typename T> ALWAYS_INLINE static bool ShouldDenyAccessToMember(T* member, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - const bool native_caller_trusted = - hiddenapi::ScopedCorePlatformApiCheck::IsCurrentCallerApproved(self); - if (native_caller_trusted) { - // A trusted caller is in the same domain as the ART module so is assumed to always have - // access to the APIs that the module provides. + if (hiddenapi::ScopedCorePlatformApiCheck::IsCurrentCallerApproved(self)) { return false; } - - // Construct AccessContext from the first calling class on stack. - // If the calling class cannot be determined, e.g. unattached threads, - // we conservatively assume the caller is trusted. return hiddenapi::ShouldDenyAccessToMember( member, [&]() REQUIRES_SHARED(Locks::mutator_lock_) { diff --git a/test/2030-core-platform-api-jni/build b/test/2030-core-platform-api-jni/build deleted file mode 100644 index 330a6def29..0000000000 --- a/test/2030-core-platform-api-jni/build +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# -# Copyright 2018 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. - -set -e - -# Build the jars twice. First with applying hiddenapi, creating a boot jar, then -# a second time without to create a normal jar. We need to do this because we -# want to load the jar once as an app module and once as a member of the boot -# class path. The DexFileVerifier would fail on the former as it does not allow -# hidden API access flags in dex files. DexFileVerifier is not invoked on boot -# class path dex files, so the boot jar loads fine in the latter case. - -export USE_HIDDENAPI=true -./default-build "$@" - -# Move the jar file into the resource folder to be bundled with the test. -mkdir res -mv ${TEST_NAME}.jar res/boot.jar - -# Clear all intermediate files otherwise default-build would either skip -# compilation or fail rebuilding. -rm -rf classes* - -export USE_HIDDENAPI=false -./default-build "$@" diff --git a/test/2030-core-platform-api-jni/check b/test/2030-core-platform-api-jni/check deleted file mode 100644 index c319a0ae97..0000000000 --- a/test/2030-core-platform-api-jni/check +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2018 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. - -# Remove pid and date from the log messages. -grep -vE '^dalvikvm(32|64) E [^]]+]' "$2" \ - | grep -v JNI_OnLoad \ - | grep -v JNI_OnUnload \ - > "$2.tmp" - -./default-check "$1" "$2.tmp" diff --git a/test/2030-core-platform-api-jni/core-platform-api-jni.cc b/test/2030-core-platform-api-jni/core-platform-api-jni.cc deleted file mode 100644 index 525982f29c..0000000000 --- a/test/2030-core-platform-api-jni/core-platform-api-jni.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -#include "hidden_api.h" -#include "hidden_api_jni.h" -#include "jni.h" -#include "runtime.h" - -#include "nativehelper/JNIHelp.h" -#include "nativehelper/ScopedLocalRef.h" -#include "nativehelper/ScopedUtfChars.h" - -class TestLibraryPathClassifier : public art::hiddenapi::JniLibraryPathClassifier { - public: - std::optional<art::hiddenapi::SharedObjectKind> Classify(const char* so_path) override { - // so_path is the path to a shared object. We have the filename minus suffix (expected to be - // .so). - const char* last_separator = strrchr(so_path, '/'); - std::string_view filename = (last_separator != nullptr) ? last_separator + 1 : so_path; - if (filename == so_name_) { - return so_kind_; - } - return {}; - } - - void Configure(const char* so_file, art::hiddenapi::SharedObjectKind kind) { - so_name_ = so_file; - so_kind_ = kind; - } - - private: - std::string so_name_; - art::hiddenapi::SharedObjectKind so_kind_ = art::hiddenapi::SharedObjectKind::kOther; -}; - -static TestLibraryPathClassifier* GetLibraryPathClassifier() { - static TestLibraryPathClassifier g_classifier; - return &g_classifier; -} - -static void InstallLibraryPathClassifier(JNIEnv* env, - jstring j_library_path, - art::hiddenapi::SharedObjectKind kind) { - ScopedUtfChars library_path(env, j_library_path); - const char* last_separator = strrchr(library_path.c_str(), '/'); - const char* library_so = (last_separator != nullptr) ? last_separator + 1 : library_path.c_str(); - GetLibraryPathClassifier()->Configure(library_so, kind); - art::hiddenapi::JniInitializeNativeCallerCheck(GetLibraryPathClassifier()); -} - -extern "C" JNIEXPORT void JNICALL Java_Main_treatAsArtModule(JNIEnv* env, - jclass /*klass*/, - jstring library_name) { - InstallLibraryPathClassifier(env, library_name, art::hiddenapi::SharedObjectKind::kArtModule); -} - -extern "C" JNIEXPORT void JNICALL Java_Main_treatAsOtherLibrary(JNIEnv* env, - jclass /*klass*/, - jstring library_name) { - InstallLibraryPathClassifier(env, library_name, art::hiddenapi::SharedObjectKind::kOther); -} diff --git a/test/2030-core-platform-api-jni/expected.txt b/test/2030-core-platform-api-jni/expected.txt deleted file mode 100644 index e69de29bb2..0000000000 --- a/test/2030-core-platform-api-jni/expected.txt +++ /dev/null diff --git a/test/2030-core-platform-api-jni/hiddenapi-flags.csv b/test/2030-core-platform-api-jni/hiddenapi-flags.csv deleted file mode 100644 index 42626f7f5c..0000000000 --- a/test/2030-core-platform-api-jni/hiddenapi-flags.csv +++ /dev/null @@ -1,108 +0,0 @@ -LNullaryConstructorBlacklistAndCorePlatformApi;-><init>()V,blacklist,core-platform-api -LNullaryConstructorBlacklist;-><init>()V,blacklist -LNullaryConstructorDarkGreylist;-><init>()V,greylist-max-o -LNullaryConstructorLightGreylist;-><init>()V,greylist -LParentClass;->fieldPackageBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldPackageBlacklist:I,blacklist -LParentClass;->fieldPackageDarkGreylist:I,greylist-max-o -LParentClass;->fieldPackageLightGreylist:I,greylist -LParentClass;->fieldPackageStaticBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldPackageStaticBlacklist:I,blacklist -LParentClass;->fieldPackageStaticDarkGreylist:I,greylist-max-o -LParentClass;->fieldPackageStaticLightGreylist:I,greylist -LParentClass;->fieldPrivateBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldPrivateBlacklist:I,blacklist -LParentClass;->fieldPrivateDarkGreylist:I,greylist-max-o -LParentClass;->fieldPrivateLightGreylist:I,greylist -LParentClass;->fieldPrivateStaticBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldPrivateStaticBlacklist:I,blacklist -LParentClass;->fieldPrivateStaticDarkGreylist:I,greylist-max-o -LParentClass;->fieldPrivateStaticLightGreylist:I,greylist -LParentClass;->fieldProtectedBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldProtectedBlacklist:I,blacklist -LParentClass;->fieldProtectedDarkGreylist:I,greylist-max-o -LParentClass;->fieldProtectedLightGreylist:I,greylist -LParentClass;->fieldProtectedStaticBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldProtectedStaticBlacklist:I,blacklist -LParentClass;->fieldProtectedStaticDarkGreylist:I,greylist-max-o -LParentClass;->fieldProtectedStaticLightGreylist:I,greylist -LParentClass;->fieldPublicBlacklistAndCorePlatformApiB:I,blacklist,core-platform-api -LParentClass;->fieldPublicBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldPublicBlacklistB:I,blacklist -LParentClass;->fieldPublicBlacklist:I,blacklist -LParentClass;->fieldPublicDarkGreylistB:I,greylist-max-o -LParentClass;->fieldPublicDarkGreylist:I,greylist-max-o -LParentClass;->fieldPublicLightGreylistB:I,greylist -LParentClass;->fieldPublicLightGreylist:I,greylist -LParentClass;->fieldPublicStaticBlacklistAndCorePlatformApiB:I,blacklist,core-platform-api -LParentClass;->fieldPublicStaticBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentClass;->fieldPublicStaticBlacklistB:I,blacklist -LParentClass;->fieldPublicStaticBlacklist:I,blacklist -LParentClass;->fieldPublicStaticDarkGreylistB:I,greylist-max-o -LParentClass;->fieldPublicStaticDarkGreylist:I,greylist-max-o -LParentClass;->fieldPublicStaticLightGreylistB:I,greylist -LParentClass;->fieldPublicStaticLightGreylist:I,greylist -LParentClass;-><init>(DB)V,greylist-max-o -LParentClass;-><init>(DC)V,blacklist -LParentClass;-><init>(DI)V,blacklist,core-platform-api -LParentClass;-><init>(DZ)V,greylist -LParentClass;-><init>(FB)V,greylist-max-o -LParentClass;-><init>(FC)V,blacklist -LParentClass;-><init>(FI)V,blacklist,core-platform-api -LParentClass;-><init>(FZ)V,greylist -LParentClass;-><init>(IB)V,greylist-max-o -LParentClass;-><init>(IC)V,blacklist -LParentClass;-><init>(II)V,blacklist,core-platform-api -LParentClass;-><init>(IZ)V,greylist -LParentClass;-><init>(JB)V,greylist-max-o -LParentClass;-><init>(JC)V,blacklist -LParentClass;-><init>(JI)V,blacklist,core-platform-api -LParentClass;-><init>(JZ)V,greylist -LParentClass;->methodPackageBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodPackageBlacklist()I,blacklist -LParentClass;->methodPackageDarkGreylist()I,greylist-max-o -LParentClass;->methodPackageLightGreylist()I,greylist -LParentClass;->methodPackageStaticBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodPackageStaticBlacklist()I,blacklist -LParentClass;->methodPackageStaticDarkGreylist()I,greylist-max-o -LParentClass;->methodPackageStaticLightGreylist()I,greylist -LParentClass;->methodPrivateBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodPrivateBlacklist()I,blacklist -LParentClass;->methodPrivateDarkGreylist()I,greylist-max-o -LParentClass;->methodPrivateLightGreylist()I,greylist -LParentClass;->methodPrivateStaticBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodPrivateStaticBlacklist()I,blacklist -LParentClass;->methodPrivateStaticDarkGreylist()I,greylist-max-o -LParentClass;->methodPrivateStaticLightGreylist()I,greylist -LParentClass;->methodProtectedBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodProtectedBlacklist()I,blacklist -LParentClass;->methodProtectedDarkGreylist()I,greylist-max-o -LParentClass;->methodProtectedLightGreylist()I,greylist -LParentClass;->methodProtectedStaticBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodProtectedStaticBlacklist()I,blacklist -LParentClass;->methodProtectedStaticDarkGreylist()I,greylist-max-o -LParentClass;->methodProtectedStaticLightGreylist()I,greylist -LParentClass;->methodPublicBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodPublicBlacklist()I,blacklist -LParentClass;->methodPublicDarkGreylist()I,greylist-max-o -LParentClass;->methodPublicLightGreylist()I,greylist -LParentClass;->methodPublicStaticBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentClass;->methodPublicStaticBlacklist()I,blacklist -LParentClass;->methodPublicStaticDarkGreylist()I,greylist-max-o -LParentClass;->methodPublicStaticLightGreylist()I,greylist -LParentInterface;->fieldPublicStaticBlacklistAndCorePlatformApi:I,blacklist,core-platform-api -LParentInterface;->fieldPublicStaticBlacklist:I,blacklist -LParentInterface;->fieldPublicStaticDarkGreylist:I,greylist-max-o -LParentInterface;->fieldPublicStaticLightGreylist:I,greylist -LParentInterface;->methodPublicBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentInterface;->methodPublicBlacklist()I,blacklist -LParentInterface;->methodPublicDarkGreylist()I,greylist-max-o -LParentInterface;->methodPublicDefaultBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentInterface;->methodPublicDefaultBlacklist()I,blacklist -LParentInterface;->methodPublicDefaultDarkGreylist()I,greylist-max-o -LParentInterface;->methodPublicDefaultLightGreylist()I,greylist -LParentInterface;->methodPublicLightGreylist()I,greylist -LParentInterface;->methodPublicStaticBlacklistAndCorePlatformApi()I,blacklist,core-platform-api -LParentInterface;->methodPublicStaticBlacklist()I,blacklist -LParentInterface;->methodPublicStaticDarkGreylist()I,greylist-max-o -LParentInterface;->methodPublicStaticLightGreylist()I,greylist diff --git a/test/2030-core-platform-api-jni/info.txt b/test/2030-core-platform-api-jni/info.txt deleted file mode 100644 index 94aac1e6d9..0000000000 --- a/test/2030-core-platform-api-jni/info.txt +++ /dev/null @@ -1,16 +0,0 @@ -Test whether hidden API access flags are being enforced. The test is composed of -two JARs. The first (parent) defines methods and fields and the second (child) -tries to access them with reflection/JNI/MethodHandles or link against them. -Note that the first is compiled twice - once with and once without hidden access -flags. - -The test then proceeds to exercise the following combinations of class loading: -(a) Both parent and child dex loaded with PathClassLoader, parent's class loader - is the child's class loader's parent. Access flags should not be enforced as - the parent does not belong to boot class path. -(b) Parent is appended to boot class path, child is loaded with PathClassLoader. - In this situation child should not be able to access hidden methods/fields - of the parent. -(c) Both parent and child are appended to boot class path. Restrictions should - not apply as hidden APIs are accessible within the boundaries of the boot - class path. diff --git a/test/2030-core-platform-api-jni/run b/test/2030-core-platform-api-jni/run deleted file mode 100755 index 2babeefbe5..0000000000 --- a/test/2030-core-platform-api-jni/run +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2019 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. - -# Make verification soft fail so that we can re-verify boot classpath -# methods at runtime. -exec ${RUN} $@ --verify-soft-fail
\ No newline at end of file diff --git a/test/2030-core-platform-api-jni/src-art/Main.java b/test/2030-core-platform-api-jni/src-art/Main.java deleted file mode 100644 index d6601dbf6e..0000000000 --- a/test/2030-core-platform-api-jni/src-art/Main.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -import dalvik.system.PathClassLoader; -import java.io.File; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.util.Arrays; - -public class Main { - // This needs to be kept in sync with DexDomain in ChildClass. - enum DexDomain { - CorePlatform, - Platform, - Application - } - - public static void main(String[] args) throws Exception { - System.loadLibrary(args[0]); - prepareNativeLibFileName(args[0]); - - // Enable hidden API checks in case they are disabled by default. - init(); - - // TODO there are sequential depencies between these test cases, and bugs - // in the production code may lead to subsequent tests to erroneously pass, - // or test the wrong thing. We rely on not deduping hidden API warnings - // here for the same reasons), meaning the code under test and production - // code are running in different configurations. Each test should be run in - // a fresh process to ensure that they are working correctly and not - // accidentally interfering with each other. - // As a side effect, we also cannot test Platform->Platform and later - // Platform->CorePlatform as the former succeeds in verifying linkage usages - // that should fail in the latter. - // We also cannot use InMemoryDexClassLoader because it runs verification in - // a background thread and being able to dynamically change the configuration - // (like list of exemptions) would require proper thread synchronization. - - // Run test with both parent and child dex files loaded with class loaders. - // The expectation is that hidden members in parent should be visible to - // the child. - doTest(DexDomain.Application, DexDomain.Application, false); - doUnloading(); - - // Now append parent dex file to boot class path and run again. This time - // the child dex file should not be able to access private APIs of the - // parent. - int parentIdx = appendToBootClassLoader(DEX_PARENT_BOOT, /* isCorePlatform */ false); - doTest(DexDomain.Platform, DexDomain.Application, false); - doUnloading(); - - // Now run the same test again, but with the blacklist exmemptions list set - // to "L" which matches everything. - doTest(DexDomain.Platform, DexDomain.Application, true); - doUnloading(); - - // Repeat the two tests above, only with parent being a core-platform dex file. - setDexDomain(parentIdx, /* isCorePlatform */ true); - doTest(DexDomain.CorePlatform, DexDomain.Application, false); - doUnloading(); - - doTest(DexDomain.CorePlatform, DexDomain.Application, true); - doUnloading(); - - // Append child to boot class path, first as a platform dex file. - // It should not be allowed to access non-public, non-core platform API members. - int childIdx = appendToBootClassLoader(DEX_CHILD, /* isCorePlatform */ false); - doTest(DexDomain.CorePlatform, DexDomain.Platform, false); - doUnloading(); - - // And finally change child to core-platform dex. With both in the boot classpath - // and both core-platform, access should be granted. - setDexDomain(childIdx, /* isCorePlatform */ true); - doTest(DexDomain.CorePlatform, DexDomain.CorePlatform, false); - doUnloading(); - } - - private static void doTest(DexDomain parentDomain, DexDomain childDomain, - boolean whitelistAllApis) throws Exception { - // Load parent dex if it is not in boot class path. - ClassLoader parentLoader = null; - if (parentDomain == DexDomain.Application) { - parentLoader = new PathClassLoader(DEX_PARENT, ClassLoader.getSystemClassLoader()); - } else { - parentLoader = BOOT_CLASS_LOADER; - } - - // Load child dex if it is not in boot class path. - ClassLoader childLoader = null; - if (childDomain == DexDomain.Application) { - childLoader = new PathClassLoader(DEX_CHILD, parentLoader); - } else { - if (parentLoader != BOOT_CLASS_LOADER) { - throw new IllegalStateException( - "DeclaringClass must be in parent class loader of CallingClass"); - } - childLoader = BOOT_CLASS_LOADER; - } - - // Create a unique copy of the native library. Each shared library can only - // be loaded once, but for some reason even classes from a class loader - // cannot register their native methods against symbols in a shared library - // loaded by their parent class loader. - String nativeLibCopy = createNativeLibCopy(parentDomain, childDomain, whitelistAllApis); - - // Set exemptions to "L" (matches all classes) if we are testing whitelisting. - setWhitelistAll(whitelistAllApis); - - // Invoke ChildClass.runTest - Class<?> childClass = Class.forName("ChildClass", true, childLoader); - Method runTestMethod = childClass.getDeclaredMethod( - "runTest", String.class, Integer.TYPE, Integer.TYPE, Integer.TYPE, Boolean.TYPE, - MethodHandle.class); - - final MethodHandle nativeLibraryLoadHooks[] = { - OTHER_LIBRARY_LOAD_HOOK, - ART_MODULE_LOAD_HOOK, - }; - - for (MethodHandle mh : nativeLibraryLoadHooks) { - int nativeDomainOrdinal; - if (mh == OTHER_LIBRARY_LOAD_HOOK) { - nativeDomainOrdinal = DexDomain.Application.ordinal(); - } else { - nativeDomainOrdinal = DexDomain.CorePlatform.ordinal(); - } - runTestMethod.invoke(null, nativeLibCopy, - parentDomain.ordinal(), childDomain.ordinal(), nativeDomainOrdinal, - whitelistAllApis, mh); - } - } - - // Routine which tries to figure out the absolute path of our native library. - private static void prepareNativeLibFileName(String arg) throws Exception { - String libName = System.mapLibraryName(arg); - Method libPathsMethod = Runtime.class.getDeclaredMethod("getLibPaths"); - libPathsMethod.setAccessible(true); - String[] libPaths = (String[]) libPathsMethod.invoke(Runtime.getRuntime()); - nativeLibFileName = null; - for (String p : libPaths) { - String candidate = p + libName; - if (new File(candidate).exists()) { - nativeLibFileName = candidate; - break; - } - } - if (nativeLibFileName == null) { - throw new IllegalStateException("Didn't find " + libName + " in " + - Arrays.toString(libPaths)); - } - } - - // Copy native library to a new file with a unique name so it does not - // conflict with other loaded instance of the same binary file. - private static String createNativeLibCopy(DexDomain parentDomain, DexDomain childDomain, - boolean whitelistAllApis) throws Exception { - String tempFileName = System.mapLibraryName( - "hiddenapitest_" + (parentDomain.ordinal()) + (childDomain.ordinal()) + - (whitelistAllApis ? "1" : "0")); - File tempFile = new File(System.getenv("DEX_LOCATION"), tempFileName); - Files.copy(new File(nativeLibFileName).toPath(), tempFile.toPath()); - return tempFile.getAbsolutePath(); - } - - private static void doUnloading() { - // Do multiple GCs to prevent rare flakiness if some other thread is - // keeping the classloader live. - for (int i = 0; i < 5; ++i) { - Runtime.getRuntime().gc(); - } - } - - private static MethodHandle getLoadLibraryHook(String methodName) { - try { - return MethodHandles.publicLookup().findStatic(Main.class, methodName, - LOAD_HOOK_METHOD_TYPE); - } catch (Throwable t) { - System.err.println("Initialization error for " + methodName + " " + t); - return null; - } - } - - private static String nativeLibFileName; - - private static final MethodType LOAD_HOOK_METHOD_TYPE = MethodType.methodType(void.class, - String.class); - private static final MethodHandle OTHER_LIBRARY_LOAD_HOOK = - getLoadLibraryHook("treatAsOtherLibrary"); - private static final MethodHandle ART_MODULE_LOAD_HOOK = - getLoadLibraryHook("treatAsArtModule"); - - private static final String DEX_PARENT = - new File(System.getenv("DEX_LOCATION"), "2030-core-platform-api-jni.jar").getAbsolutePath(); - private static final String DEX_PARENT_BOOT = - new File(new File(System.getenv("DEX_LOCATION"), "res"), "boot.jar").getAbsolutePath(); - private static final String DEX_CHILD = - new File(System.getenv("DEX_LOCATION"), "2030-core-platform-api-jni-ex.jar").getAbsolutePath(); - - private static ClassLoader BOOT_CLASS_LOADER = Object.class.getClassLoader(); - - private static native int appendToBootClassLoader(String dexPath, boolean isCorePlatform); - private static native void setDexDomain(int index, boolean isCorePlatform); - private static native void init(); - private static native void setWhitelistAll(boolean value); - - public static native void treatAsArtModule(String library); - public static native void treatAsOtherLibrary(String library); -} diff --git a/test/2030-core-platform-api-jni/src-ex/ChildClass.java b/test/2030-core-platform-api-jni/src-ex/ChildClass.java deleted file mode 100644 index 75fed41ed6..0000000000 --- a/test/2030-core-platform-api-jni/src-ex/ChildClass.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -import dalvik.system.VMRuntime; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.util.function.Consumer; - -public class ChildClass { - enum PrimitiveType { - TInteger('I', Integer.TYPE, Integer.valueOf(0)), - TLong('J', Long.TYPE, Long.valueOf(0)), - TFloat('F', Float.TYPE, Float.valueOf(0)), - TDouble('D', Double.TYPE, Double.valueOf(0)), - TBoolean('Z', Boolean.TYPE, Boolean.valueOf(false)), - TByte('B', Byte.TYPE, Byte.valueOf((byte) 0)), - TShort('S', Short.TYPE, Short.valueOf((short) 0)), - TCharacter('C', Character.TYPE, Character.valueOf('0')); - - PrimitiveType(char shorty, Class klass, Object value) { - mShorty = shorty; - mClass = klass; - mDefaultValue = value; - } - - public char mShorty; - public Class mClass; - public Object mDefaultValue; - } - - enum Hiddenness { - Whitelist(PrimitiveType.TShort), - LightGreylist(PrimitiveType.TBoolean), - DarkGreylist(PrimitiveType.TByte), - Blacklist(PrimitiveType.TCharacter), - BlacklistAndCorePlatformApi(PrimitiveType.TInteger); - - Hiddenness(PrimitiveType type) { mAssociatedType = type; } - public PrimitiveType mAssociatedType; - } - - enum Visibility { - Public(PrimitiveType.TInteger), - Package(PrimitiveType.TFloat), - Protected(PrimitiveType.TLong), - Private(PrimitiveType.TDouble); - - Visibility(PrimitiveType type) { mAssociatedType = type; } - public PrimitiveType mAssociatedType; - } - - enum Behaviour { - Granted, - Warning, - Denied, - } - - // This needs to be kept in sync with DexDomain in Main. - enum DexDomain { - CorePlatform, - Platform, - Application - } - - private static final boolean booleanValues[] = new boolean[] { false, true }; - - public static void runTest(String libFileName, int parentDomainOrdinal, - int childDomainOrdinal, int childNativeDomainOrdinal, - boolean everythingWhitelisted, - MethodHandle postSystemLoadHook) throws Throwable { - System.load(libFileName); - - // Configure domain of native library. - postSystemLoadHook.invokeExact(libFileName); - - parentDomain = DexDomain.values()[parentDomainOrdinal]; - childDomain = DexDomain.values()[childDomainOrdinal]; - childNativeDomain = DexDomain.values()[childNativeDomainOrdinal]; - - configMessage = "parentDomain=" + parentDomain.name() + - ", childDomain=" + childDomain.name() + - ", childNativeDomain=" + childNativeDomain.name() + - ", everythingWhitelisted=" + everythingWhitelisted; - - // Check expectations about loading into boot class path. - boolean isParentInBoot = (ParentClass.class.getClassLoader().getParent() == null); - boolean expectedParentInBoot = (parentDomain != DexDomain.Application); - if (isParentInBoot != expectedParentInBoot) { - throw new RuntimeException("Expected ParentClass " + - (expectedParentInBoot ? "" : "not ") + "in boot class path"); - } - boolean isChildInBoot = (ChildClass.class.getClassLoader().getParent() == null); - boolean expectedChildInBoot = (childDomain != DexDomain.Application); - if (isChildInBoot != expectedChildInBoot) { - throw new RuntimeException("Expected ChildClass " + (expectedChildInBoot ? "" : "not ") + - "in boot class path"); - } - ChildClass.everythingWhitelisted = everythingWhitelisted; - - boolean isSameBoot = (isParentInBoot == isChildInBoot); - boolean isDebuggable = VMRuntime.getRuntime().isJavaDebuggable(); - - // For compat reasons, meta-reflection should still be usable by apps if hidden api check - // hardening is disabled (i.e. target SDK is Q or earlier). The only configuration where this - // workaround used to work is for ChildClass in the Application domain and ParentClass in the - // Platform domain, so only test that configuration with hidden api check hardening disabled. - boolean testHiddenApiCheckHardeningDisabled = - (childDomain == DexDomain.Application) && (parentDomain == DexDomain.Platform); - - // Run meaningful combinations of access flags. - for (Hiddenness hiddenness : Hiddenness.values()) { - Behaviour expected; - final boolean invokesMemberCallback; - // Warnings are now disabled whenever access is granted, even for - // greylisted APIs. This is the behaviour for release builds. - if (everythingWhitelisted || hiddenness == Hiddenness.Whitelist) { - expected = Behaviour.Granted; - invokesMemberCallback = false; - } else if (parentDomain == DexDomain.CorePlatform && childDomain == DexDomain.Platform) { - expected = (hiddenness == Hiddenness.BlacklistAndCorePlatformApi) - ? Behaviour.Granted : Behaviour.Denied; - invokesMemberCallback = false; - } else if (isSameBoot) { - expected = Behaviour.Granted; - invokesMemberCallback = false; - } else if (hiddenness == Hiddenness.Blacklist || - hiddenness == Hiddenness.BlacklistAndCorePlatformApi) { - expected = Behaviour.Denied; - invokesMemberCallback = true; - } else { - expected = Behaviour.Warning; - invokesMemberCallback = true; - } - - if (childNativeDomain == DexDomain.CorePlatform) { - // Native code that is part of the Core Platform (it's in the ART module). This code is - // assumed to have access to all methods and fields. - expected = Behaviour.Granted; - } - - for (boolean isStatic : booleanValues) { - String suffix = (isStatic ? "Static" : "") + hiddenness.name(); - - for (Visibility visibility : Visibility.values()) { - // Test methods and fields - for (Class klass : new Class<?>[] { ParentClass.class, ParentInterface.class }) { - String baseName = visibility.name() + suffix; - checkField(klass, "field" + baseName, isStatic, visibility, expected, - invokesMemberCallback, testHiddenApiCheckHardeningDisabled); - checkMethod(klass, "method" + baseName, isStatic, visibility, expected, - invokesMemberCallback, testHiddenApiCheckHardeningDisabled); - } - - // Check whether one can use a class constructor. - checkConstructor(ParentClass.class, visibility, hiddenness, expected, - testHiddenApiCheckHardeningDisabled); - } - } - } - } - - private static void checkField(Class<?> klass, String name, boolean isStatic, - Visibility visibility, Behaviour behaviour, boolean invokesMemberCallback, - boolean testHiddenApiCheckHardeningDisabled) throws Exception { - - boolean isPublic = (visibility == Visibility.Public); - boolean canDiscover = (behaviour != Behaviour.Denied); - - if (klass.isInterface() && (!isStatic || !isPublic)) { - // Interfaces only have public static fields. - return; - } - - // Test discovery with JNI. - - if (JNI.canDiscoverField(klass, name, isStatic) != canDiscover) { - throwDiscoveryException(klass, name, true, "JNI", canDiscover); - } - - if (canDiscover) { - if (!JNI.canGetField(klass, name, isStatic)) { - throwAccessException(klass, name, true, "getIntField"); - } - if (!JNI.canSetField(klass, name, isStatic)) { - throwAccessException(klass, name, true, "setIntField"); - } - } - } - - private static void checkMethod(Class<?> klass, String name, boolean isStatic, - Visibility visibility, Behaviour behaviour, boolean invokesMemberCallback, - boolean testHiddenApiCheckHardeningDisabled) throws Exception { - - boolean isPublic = (visibility == Visibility.Public); - if (klass.isInterface() && !isPublic) { - // All interface members are public. - return; - } - - boolean canDiscover = (behaviour != Behaviour.Denied); - - // Test discovery with JNI. - - if (JNI.canDiscoverMethod(klass, name, isStatic) != canDiscover) { - throwDiscoveryException(klass, name, false, "JNI", canDiscover); - } - - // Finish here if we could not discover the method. - - if (canDiscover) { - // Test whether we can invoke the method. This skips non-static interface methods. - if (!klass.isInterface() || isStatic) { - if (!JNI.canInvokeMethodA(klass, name, isStatic)) { - throwAccessException(klass, name, false, "CallMethodA"); - } - if (!JNI.canInvokeMethodV(klass, name, isStatic)) { - throwAccessException(klass, name, false, "CallMethodV"); - } - } - } - } - - private static void checkConstructor(Class<?> klass, Visibility visibility, Hiddenness hiddenness, - Behaviour behaviour, boolean testHiddenApiCheckHardeningDisabled) throws Exception { - - boolean isPublic = (visibility == Visibility.Public); - String signature = "(" + visibility.mAssociatedType.mShorty + - hiddenness.mAssociatedType.mShorty + ")V"; - String fullName = "<init>" + signature; - Class<?> args[] = new Class[] { visibility.mAssociatedType.mClass, - hiddenness.mAssociatedType.mClass }; - Object initargs[] = new Object[] { visibility.mAssociatedType.mDefaultValue, - hiddenness.mAssociatedType.mDefaultValue }; - MethodType methodType = MethodType.methodType(void.class, args); - - boolean canDiscover = (behaviour != Behaviour.Denied); - - // Test discovery with JNI. - - if (JNI.canDiscoverConstructor(klass, signature) != canDiscover) { - throwDiscoveryException(klass, fullName, false, "JNI", canDiscover); - } - } - - private static void throwDiscoveryException(Class<?> klass, String name, boolean isField, - String fn, boolean canAccess) { - throw new RuntimeException("Expected " + (isField ? "field " : "method ") + klass.getName() + - "." + name + " to " + (canAccess ? "" : "not ") + "be discoverable with " + fn + ". " + - configMessage); - } - - private static void throwAccessException(Class<?> klass, String name, boolean isField, - String fn) { - throw new RuntimeException("Expected to be able to access " + (isField ? "field " : "method ") + - klass.getName() + "." + name + " using " + fn + ". " + configMessage); - } - - private static void throwModifiersException(Class<?> klass, String name, boolean isField) { - throw new RuntimeException("Expected " + (isField ? "field " : "method ") + klass.getName() + - "." + name + " to not expose hidden modifiers"); - } - - private static DexDomain parentDomain; - private static DexDomain childDomain; - private static DexDomain childNativeDomain; - private static boolean everythingWhitelisted; - - private static String configMessage; -} diff --git a/test/2030-core-platform-api-jni/src-ex/JNI.java b/test/2030-core-platform-api-jni/src-ex/JNI.java deleted file mode 100644 index 5dfb2963fa..0000000000 --- a/test/2030-core-platform-api-jni/src-ex/JNI.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -public class JNI { - public static native boolean canDiscoverField(Class<?> klass, String name, boolean isStatic); - public static native boolean canGetField(Class<?> klass, String name, boolean isStatic); - public static native boolean canSetField(Class<?> klass, String name, boolean isStatic); - - public static native boolean canDiscoverMethod(Class<?> klass, String name, boolean isStatic); - public static native boolean canInvokeMethodA(Class<?> klass, String name, boolean isStatic); - public static native boolean canInvokeMethodV(Class<?> klass, String name, boolean isStatic); - - public static native boolean canDiscoverConstructor(Class<?> klass, String signature); - public static native boolean canInvokeConstructorA(Class<?> klass, String signature); - public static native boolean canInvokeConstructorV(Class<?> klass, String signature); -} diff --git a/test/2030-core-platform-api-jni/src/DummyClass.java b/test/2030-core-platform-api-jni/src/DummyClass.java deleted file mode 100644 index afba74710f..0000000000 --- a/test/2030-core-platform-api-jni/src/DummyClass.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -public class DummyClass implements ParentInterface { - public int methodPublicWhitelist() { return 1; } - public int methodPublicLightGreylist() { return 2; } - public int methodPublicDarkGreylist() { return 3; } - public int methodPublicBlacklist() { return 4; } - public int methodPublicBlacklistAndCorePlatformApi() { return 5; } - - public static ParentInterface getInterfaceInstance() { - return new DummyClass(); - } -} diff --git a/test/2030-core-platform-api-jni/src/NullaryConstructorBlacklist.java b/test/2030-core-platform-api-jni/src/NullaryConstructorBlacklist.java deleted file mode 100644 index 5bf6278a77..0000000000 --- a/test/2030-core-platform-api-jni/src/NullaryConstructorBlacklist.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -public class NullaryConstructorBlacklist { - public NullaryConstructorBlacklist() { x = 22; } - public NullaryConstructorBlacklist(int y) { x = y; } - protected int x; -} diff --git a/test/2030-core-platform-api-jni/src/NullaryConstructorBlacklistAndCorePlatformApi.java b/test/2030-core-platform-api-jni/src/NullaryConstructorBlacklistAndCorePlatformApi.java deleted file mode 100644 index 86af29e7f0..0000000000 --- a/test/2030-core-platform-api-jni/src/NullaryConstructorBlacklistAndCorePlatformApi.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -public class NullaryConstructorBlacklistAndCorePlatformApi { - public NullaryConstructorBlacklistAndCorePlatformApi() { x = 22; } - public NullaryConstructorBlacklistAndCorePlatformApi(int y) { x = y; } - protected int x; -} diff --git a/test/2030-core-platform-api-jni/src/NullaryConstructorDarkGreylist.java b/test/2030-core-platform-api-jni/src/NullaryConstructorDarkGreylist.java deleted file mode 100644 index c25a767d1d..0000000000 --- a/test/2030-core-platform-api-jni/src/NullaryConstructorDarkGreylist.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -public class NullaryConstructorDarkGreylist { - public NullaryConstructorDarkGreylist() { x = 22; } - public NullaryConstructorDarkGreylist(int y) { x = y; } - protected int x; -} diff --git a/test/2030-core-platform-api-jni/src/NullaryConstructorLightGreylist.java b/test/2030-core-platform-api-jni/src/NullaryConstructorLightGreylist.java deleted file mode 100644 index d5dac8b7c0..0000000000 --- a/test/2030-core-platform-api-jni/src/NullaryConstructorLightGreylist.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -public class NullaryConstructorLightGreylist { - public NullaryConstructorLightGreylist() { x = 22; } - public NullaryConstructorLightGreylist(int y) { x = y; } - protected int x; -} diff --git a/test/2030-core-platform-api-jni/src/NullaryConstructorWhitelist.java b/test/2030-core-platform-api-jni/src/NullaryConstructorWhitelist.java deleted file mode 100644 index d1019077cf..0000000000 --- a/test/2030-core-platform-api-jni/src/NullaryConstructorWhitelist.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -public class NullaryConstructorWhitelist { - public NullaryConstructorWhitelist() { x = 22; } - public NullaryConstructorWhitelist(int y) { x = y; } - protected int x; -} diff --git a/test/2030-core-platform-api-jni/src/ParentClass.java b/test/2030-core-platform-api-jni/src/ParentClass.java deleted file mode 100644 index 1442392857..0000000000 --- a/test/2030-core-platform-api-jni/src/ParentClass.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -public class ParentClass { - public ParentClass() {} - - // INSTANCE FIELD - - public int fieldPublicWhitelist = 211; - int fieldPackageWhitelist = 212; - protected int fieldProtectedWhitelist = 213; - private int fieldPrivateWhitelist = 214; - public int fieldPublicWhitelistB = 215; - - public int fieldPublicLightGreylist = 221; - int fieldPackageLightGreylist = 222; - protected int fieldProtectedLightGreylist = 223; - private int fieldPrivateLightGreylist = 224; - public int fieldPublicLightGreylistB = 225; - - public int fieldPublicDarkGreylist = 231; - int fieldPackageDarkGreylist = 232; - protected int fieldProtectedDarkGreylist = 233; - private int fieldPrivateDarkGreylist = 234; - public int fieldPublicDarkGreylistB = 235; - - public int fieldPublicBlacklist = 241; - int fieldPackageBlacklist = 242; - protected int fieldProtectedBlacklist = 243; - private int fieldPrivateBlacklist = 244; - public int fieldPublicBlacklistB = 245; - - public int fieldPublicBlacklistAndCorePlatformApi = 251; - int fieldPackageBlacklistAndCorePlatformApi = 252; - protected int fieldProtectedBlacklistAndCorePlatformApi = 253; - private int fieldPrivateBlacklistAndCorePlatformApi = 254; - public int fieldPublicBlacklistAndCorePlatformApiB = 255; - - // STATIC FIELD - - public static int fieldPublicStaticWhitelist = 111; - static int fieldPackageStaticWhitelist = 112; - protected static int fieldProtectedStaticWhitelist = 113; - private static int fieldPrivateStaticWhitelist = 114; - public static int fieldPublicStaticWhitelistB = 115; - - public static int fieldPublicStaticLightGreylist = 121; - static int fieldPackageStaticLightGreylist = 122; - protected static int fieldProtectedStaticLightGreylist = 123; - private static int fieldPrivateStaticLightGreylist = 124; - public static int fieldPublicStaticLightGreylistB = 125; - - public static int fieldPublicStaticDarkGreylist = 131; - static int fieldPackageStaticDarkGreylist = 132; - protected static int fieldProtectedStaticDarkGreylist = 133; - private static int fieldPrivateStaticDarkGreylist = 134; - public static int fieldPublicStaticDarkGreylistB = 135; - - public static int fieldPublicStaticBlacklist = 141; - static int fieldPackageStaticBlacklist = 142; - protected static int fieldProtectedStaticBlacklist = 143; - private static int fieldPrivateStaticBlacklist = 144; - public static int fieldPublicStaticBlacklistB = 145; - - public static int fieldPublicStaticBlacklistAndCorePlatformApi = 151; - static int fieldPackageStaticBlacklistAndCorePlatformApi = 152; - protected static int fieldProtectedStaticBlacklistAndCorePlatformApi = 153; - private static int fieldPrivateStaticBlacklistAndCorePlatformApi = 154; - public static int fieldPublicStaticBlacklistAndCorePlatformApiB = 155; - - // INSTANCE METHOD - - public int methodPublicWhitelist() { return 411; } - int methodPackageWhitelist() { return 412; } - protected int methodProtectedWhitelist() { return 413; } - private int methodPrivateWhitelist() { return 414; } - - public int methodPublicLightGreylist() { return 421; } - int methodPackageLightGreylist() { return 422; } - protected int methodProtectedLightGreylist() { return 423; } - private int methodPrivateLightGreylist() { return 424; } - - public int methodPublicDarkGreylist() { return 431; } - int methodPackageDarkGreylist() { return 432; } - protected int methodProtectedDarkGreylist() { return 433; } - private int methodPrivateDarkGreylist() { return 434; } - - public int methodPublicBlacklist() { return 441; } - int methodPackageBlacklist() { return 442; } - protected int methodProtectedBlacklist() { return 443; } - private int methodPrivateBlacklist() { return 444; } - - public int methodPublicBlacklistAndCorePlatformApi() { return 451; } - int methodPackageBlacklistAndCorePlatformApi() { return 452; } - protected int methodProtectedBlacklistAndCorePlatformApi() { return 453; } - private int methodPrivateBlacklistAndCorePlatformApi() { return 454; } - - // STATIC METHOD - - public static int methodPublicStaticWhitelist() { return 311; } - static int methodPackageStaticWhitelist() { return 312; } - protected static int methodProtectedStaticWhitelist() { return 313; } - private static int methodPrivateStaticWhitelist() { return 314; } - - public static int methodPublicStaticLightGreylist() { return 321; } - static int methodPackageStaticLightGreylist() { return 322; } - protected static int methodProtectedStaticLightGreylist() { return 323; } - private static int methodPrivateStaticLightGreylist() { return 324; } - - public static int methodPublicStaticDarkGreylist() { return 331; } - static int methodPackageStaticDarkGreylist() { return 332; } - protected static int methodProtectedStaticDarkGreylist() { return 333; } - private static int methodPrivateStaticDarkGreylist() { return 334; } - - public static int methodPublicStaticBlacklist() { return 341; } - static int methodPackageStaticBlacklist() { return 342; } - protected static int methodProtectedStaticBlacklist() { return 343; } - private static int methodPrivateStaticBlacklist() { return 344; } - - public static int methodPublicStaticBlacklistAndCorePlatformApi() { return 351; } - static int methodPackageStaticBlacklistAndCorePlatformApi() { return 352; } - protected static int methodProtectedStaticBlacklistAndCorePlatformApi() { return 353; } - private static int methodPrivateStaticBlacklistAndCorePlatformApi() { return 354; } - - // CONSTRUCTOR - - // Whitelist - public ParentClass(int x, short y) {} - ParentClass(float x, short y) {} - protected ParentClass(long x, short y) {} - private ParentClass(double x, short y) {} - - // Light greylist - public ParentClass(int x, boolean y) {} - ParentClass(float x, boolean y) {} - protected ParentClass(long x, boolean y) {} - private ParentClass(double x, boolean y) {} - - // Dark greylist - public ParentClass(int x, byte y) {} - ParentClass(float x, byte y) {} - protected ParentClass(long x, byte y) {} - private ParentClass(double x, byte y) {} - - // Blacklist - public ParentClass(int x, char y) {} - ParentClass(float x, char y) {} - protected ParentClass(long x, char y) {} - private ParentClass(double x, char y) {} - - // Blacklist and CorePlatformApi - public ParentClass(int x, int y) {} - ParentClass(float x, int y) {} - protected ParentClass(long x, int y) {} - private ParentClass(double x, int y) {} - - // HELPERS - - public int callMethodPublicWhitelist() { return methodPublicWhitelist(); } - public int callMethodPackageWhitelist() { return methodPackageWhitelist(); } - public int callMethodProtectedWhitelist() { return methodProtectedWhitelist(); } - - public int callMethodPublicLightGreylist() { return methodPublicLightGreylist(); } - public int callMethodPackageLightGreylist() { return methodPackageLightGreylist(); } - public int callMethodProtectedLightGreylist() { return methodProtectedLightGreylist(); } - - public int callMethodPublicDarkGreylist() { return methodPublicDarkGreylist(); } - public int callMethodPackageDarkGreylist() { return methodPackageDarkGreylist(); } - public int callMethodProtectedDarkGreylist() { return methodProtectedDarkGreylist(); } - - public int callMethodPublicBlacklist() { return methodPublicBlacklist(); } - public int callMethodPackageBlacklist() { return methodPackageBlacklist(); } - public int callMethodProtectedBlacklist() { return methodProtectedBlacklist(); } - - public int callMethodPublicBlacklistAndCorePlatformApi() { - return methodPublicBlacklistAndCorePlatformApi(); - } - - public int callMethodPackageBlacklistAndCorePlatformApi() { - return methodPackageBlacklistAndCorePlatformApi(); - } - - public int callMethodProtectedBlacklistAndCorePlatformApi() { - return methodProtectedBlacklistAndCorePlatformApi(); - } -} diff --git a/test/2030-core-platform-api-jni/src/ParentInterface.java b/test/2030-core-platform-api-jni/src/ParentInterface.java deleted file mode 100644 index 1c5b58f73b..0000000000 --- a/test/2030-core-platform-api-jni/src/ParentInterface.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -public interface ParentInterface { - // STATIC FIELD - static int fieldPublicStaticWhitelist = 11; - static int fieldPublicStaticLightGreylist = 12; - static int fieldPublicStaticDarkGreylist = 13; - static int fieldPublicStaticBlacklist = 14; - static int fieldPublicStaticBlacklistAndCorePlatformApi = 15; - - // INSTANCE METHOD - int methodPublicWhitelist(); - int methodPublicLightGreylist(); - int methodPublicDarkGreylist(); - int methodPublicBlacklist(); - int methodPublicBlacklistAndCorePlatformApi(); - - // STATIC METHOD - static int methodPublicStaticWhitelist() { return 21; } - static int methodPublicStaticLightGreylist() { return 22; } - static int methodPublicStaticDarkGreylist() { return 23; } - static int methodPublicStaticBlacklist() { return 24; } - static int methodPublicStaticBlacklistAndCorePlatformApi() { return 25; } - - // DEFAULT METHOD - default int methodPublicDefaultWhitelist() { return 31; } - default int methodPublicDefaultLightGreylist() { return 32; } - default int methodPublicDefaultDarkGreylist() { return 33; } - default int methodPublicDefaultBlacklist() { return 34; } - default int methodPublicDefaultBlacklistAndCorePlatformApi() { return 35; } -} diff --git a/test/Android.bp b/test/Android.bp index 92d8d260e1..9a5bcb5ffd 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -601,7 +601,6 @@ cc_defaults { "1972-jni-id-swap-indices/jni_id.cc", "1985-structural-redefine-stack-scope/stack_scope.cc", "2011-stack-walk-concurrent-instrument/stack_walk_concurrent.cc", - "2030-core-platform-api-jni/core-platform-api-jni.cc", "common/runtime_state.cc", "common/stack_inspect.cc", ], diff --git a/test/knownfailures.json b/test/knownfailures.json index f5d51c1a2e..afddc81abb 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -490,8 +490,7 @@ "607-daemon-stress", "674-hiddenapi", "687-deopt", - "904-object-allocation", - "2030-core-platform-api-jni" + "904-object-allocation" ], "description": ["Tests that sometimes fail when run with jvmti-stress for unknown reasons."], "bug": "b/120995005", @@ -545,8 +544,7 @@ "690-hiddenapi-same-name-methods", "804-class-extends-itself", "921-hello-failure", - "999-redefine-hiddenapi", - "2030-core-platform-api-jni" + "999-redefine-hiddenapi" ], "description": [ "Tests that use illegal dex files or otherwise break dexter assumptions" @@ -568,8 +566,7 @@ "692-vdex-inmem-loader", "693-vdex-inmem-loader-evict", "944-transform-classloaders", - "999-redefine-hiddenapi", - "2030-core-platform-api-jni" + "999-redefine-hiddenapi" ], "description": [ "Tests that use custom class loaders or other features not supported ", @@ -1207,8 +1204,7 @@ "2004-double-virtual-structural-abstract", "2005-pause-all-redefine-multithreaded", "2006-virtual-structural-finalizing", - "2007-virtual-structural-finalizable", - "2030-core-platform-api-jni" + "2007-virtual-structural-finalizable" ], "variant": "jvm", "description": ["Doesn't run on RI."] |