Refactor enforcement of hidden API policy when linking
Hidden API enforcement when linking was sub-optimal for two reasons:
a) it was based on Class::CanAccessMember and would throw
IllegalAccessError instead of NoSuchMethodError/NoSuchFieldError, and
b) no warnings were printed in the code path.
This patch moves the checks into ClassLinker's resolution routines and
uses a code path which prints warning.
Bug: 64382372
Test: art/test.py -r -t 674-hiddenapi
Change-Id: I8a0fbdca58ce5803c1588b644a3e627a0a9a6504
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 72c110a..9990a37 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -7907,6 +7907,10 @@
resolved = klass->FindClassMethod(dex_cache, method_idx, image_pointer_size_);
}
DCHECK(resolved == nullptr || resolved->GetDeclaringClassUnchecked() != nullptr);
+ if (resolved != nullptr &&
+ hiddenapi::ShouldBlockAccessToMember(resolved, class_loader, hiddenapi::kLinking)) {
+ resolved = nullptr;
+ }
if (resolved != nullptr) {
// In case of jmvti, the dex file gets verified before being registered, so first
// check if it's registered before checking class tables.
@@ -8045,7 +8049,10 @@
} else {
resolved = klass->FindClassMethod(dex_cache.Get(), method_idx, image_pointer_size_);
}
-
+ if (resolved != nullptr &&
+ hiddenapi::ShouldBlockAccessToMember(resolved, class_loader.Get(), hiddenapi::kLinking)) {
+ resolved = nullptr;
+ }
return resolved;
}
@@ -8119,11 +8126,16 @@
} else {
resolved = klass->FindInstanceField(name, type);
}
- if (resolved == nullptr) {
- ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass, type, name);
- return nullptr;
- }
}
+
+ if (resolved == nullptr ||
+ hiddenapi::ShouldBlockAccessToMember(resolved, class_loader.Get(), hiddenapi::kLinking)) {
+ const char* name = dex_file.GetFieldName(field_id);
+ const char* type = dex_file.GetFieldTypeDescriptor(field_id);
+ ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass, type, name);
+ return nullptr;
+ }
+
dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
return resolved;
}
@@ -8149,6 +8161,10 @@
StringPiece name(dex_file.GetFieldName(field_id));
StringPiece type(dex_file.GetFieldTypeDescriptor(field_id));
resolved = mirror::Class::FindField(self, klass, name, type);
+ if (resolved != nullptr &&
+ hiddenapi::ShouldBlockAccessToMember(resolved, class_loader.Get(), hiddenapi::kLinking)) {
+ resolved = nullptr;
+ }
if (resolved != nullptr) {
dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
} else {