Hide conscrypt package classes for app AOT compilation.
Since app AOT compilation is usually done without conscrypt
on the boot class path, classes defined by app class loader
in conscrypt packages could be resolved differently, i.e.
from conscrypt, at runtime. Reject such definitions during
AOT compilation to ensure correct runtime behavior.
Add a test that when compiling the conscrypt module as an
app, we cannot resolve any class defined in its dex files.
Test: module_exclusion_test
Bug: 122937705
Change-Id: I1fcb4c21937f59772206ee50b688a75053231bc0
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index a27b28e..97c3b18 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -44,6 +44,7 @@
#include "base/scoped_arena_containers.h"
#include "base/scoped_flock.h"
#include "base/stl_util.h"
+#include "base/string_view_cpp20.h"
#include "base/systrace.h"
#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
@@ -3007,6 +3008,13 @@
return result_ptr;
}
+static bool IsReservedBootClassPathDescriptor(const char* descriptor) {
+ std::string_view descriptor_sv(descriptor);
+ // Reserved conscrypt packages (includes sub-packages under these paths).
+ return StartsWith(descriptor_sv, "Landroid/net/ssl/") ||
+ StartsWith(descriptor_sv, "Lcom/android/org/conscrypt/");
+}
+
ObjPtr<mirror::Class> ClassLinker::DefineClass(Thread* self,
const char* descriptor,
size_t hash,
@@ -3034,6 +3042,18 @@
}
}
+ // For AOT-compilation of an app, we may use a shortened boot class path that excludes
+ // some runtime modules. Prevent definition of classes in app class loader that could clash
+ // with these modules as these classes could be resolved differently during execution.
+ if (class_loader != nullptr &&
+ Runtime::Current()->IsAotCompiler() &&
+ IsReservedBootClassPathDescriptor(descriptor)) {
+ ObjPtr<mirror::Throwable> pre_allocated =
+ Runtime::Current()->GetPreAllocatedNoClassDefFoundError();
+ self->SetException(pre_allocated);
+ return nullptr;
+ }
+
// This is to prevent the calls to ClassLoad and ClassPrepare which can cause java/user-supplied
// code to be executed. We put it up here so we can avoid all the allocations associated with
// creating the class. This can happen with (eg) jit threads.