Revert "Fix Core Platform API JNI check"
This reverts commit 6c56db31b8a6424680ad3836022a1d81e83dc4a9.
Reason for revert: potential culprit b/149238651
Bug: 144502743
Bug: 149238651
Change-Id: I719ecaff2c9486776b165918607a2df2ee23d56d
diff --git a/runtime/hidden_api_jni.cc b/runtime/hidden_api_jni.cc
index 2e32224..074c4c3 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 @@
// 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 @@
};
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 @@
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 @@
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 @@
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 @@
}
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 @@
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;
}
+ art::MemoryTypeTable<SharedObjectKind> memory_type_table_;
+
// 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_);
-
- // Classifier used to override shared object classifications during tests.
- JniLibraryPathClassifier* fc_classifier_ GUARDED_BY(mutex_) = nullptr;
+ 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 @@
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 @@
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 @@
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 15de6ef..a084378 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 @@
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 887ad9a..882e10f 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -88,17 +88,9 @@
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 330a6de..0000000
--- 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 c319a0a..0000000
--- 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 525982f..0000000
--- 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 e69de29..0000000
--- 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 42626f7..0000000
--- 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 94aac1e..0000000
--- 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 2babeef..0000000
--- 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 d6601db..0000000
--- 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 75fed41..0000000
--- 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 5dfb296..0000000
--- 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 afba747..0000000
--- 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 5bf6278..0000000
--- 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 86af29e..0000000
--- 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 c25a767..0000000
--- 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 d5dac8b..0000000
--- 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 d101907..0000000
--- 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 1442392..0000000
--- 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 1c5b58f..0000000
--- 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 92d8d26..9a5bcb5 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -601,7 +601,6 @@
"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 f5d51c1..afddc81 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."]