summaryrefslogtreecommitdiff
path: root/artd
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2023-08-14 11:08:03 +0100
committer Jiakai Zhang <jiakaiz@google.com> 2023-10-10 19:01:06 +0000
commit8d5f52e883f25c2bba17b74b58cac43851a7fb23 (patch)
treef61f58882cd67c6c4e2443ce3fb4dff66ac5d6ca /artd
parent07b3996128bcc5f6cdc6421f72d89c12cbdabd7a (diff)
Validate dex paths and class loader contexts reported by apps.
Invalid dex paths and class loader contexts are considered as fatal errors. We should not let apps trigger those errors. Bug: 295271514 Test: atest CtsCompilationTestCases Change-Id: I0431da3db024f77623d559eafe3b144ef532d31f Merged-In: I0431da3db024f77623d559eafe3b144ef532d31f
Diffstat (limited to 'artd')
-rw-r--r--artd/artd.cc38
-rw-r--r--artd/artd.h7
-rw-r--r--artd/binder/com/android/server/art/IArtd.aidl13
3 files changed, 58 insertions, 0 deletions
diff --git a/artd/artd.cc b/artd/artd.cc
index 4558b33988..502942e82a 100644
--- a/artd/artd.cc
+++ b/artd/artd.cc
@@ -1103,6 +1103,44 @@ ScopedAStatus Artd::isInDalvikCache(const std::string& in_dexFile, bool* _aidl_r
return NonFatal(ART_FORMAT("Fstab entries not found for '{}'", in_dexFile));
}
+ScopedAStatus Artd::validateDexPath(const std::string& in_dexPath,
+ std::optional<std::string>* _aidl_return) {
+ if (Result<void> result = ValidateDexPath(in_dexPath); !result.ok()) {
+ *_aidl_return = result.error().message();
+ } else {
+ *_aidl_return = std::nullopt;
+ }
+ return ScopedAStatus::ok();
+}
+
+ScopedAStatus Artd::validateClassLoaderContext(const std::string& in_dexPath,
+ const std::string& in_classLoaderContext,
+ std::optional<std::string>* _aidl_return) {
+ if (in_classLoaderContext == ClassLoaderContext::kUnsupportedClassLoaderContextEncoding) {
+ *_aidl_return = std::nullopt;
+ return ScopedAStatus::ok();
+ }
+
+ std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(in_classLoaderContext);
+ if (context == nullptr) {
+ *_aidl_return = ART_FORMAT("Class loader context '{}' is invalid", in_classLoaderContext);
+ return ScopedAStatus::ok();
+ }
+
+ std::vector<std::string> flattened_context = context->FlattenDexPaths();
+ std::string dex_dir = Dirname(in_dexPath);
+ for (const std::string& context_element : flattened_context) {
+ std::string context_path = std::filesystem::path(dex_dir).append(context_element);
+ if (Result<void> result = ValidateDexPath(context_path); !result.ok()) {
+ *_aidl_return = result.error().message();
+ return ScopedAStatus::ok();
+ }
+ }
+
+ *_aidl_return = std::nullopt;
+ return ScopedAStatus::ok();
+}
+
Result<void> Artd::Start() {
OR_RETURN(SetLogVerbosity());
diff --git a/artd/artd.h b/artd/artd.h
index 2386cfbfa1..a4012c6da1 100644
--- a/artd/artd.h
+++ b/artd/artd.h
@@ -166,6 +166,13 @@ class Artd : public aidl::com::android::server::art::BnArtd {
ndk::ScopedAStatus isInDalvikCache(const std::string& in_dexFile, bool* _aidl_return) override;
+ ndk::ScopedAStatus validateDexPath(const std::string& in_dexPath,
+ std::optional<std::string>* _aidl_return) override;
+
+ ndk::ScopedAStatus validateClassLoaderContext(const std::string& in_dexPath,
+ const std::string& in_classLoaderContext,
+ std::optional<std::string>* _aidl_return) override;
+
android::base::Result<void> Start();
private:
diff --git a/artd/binder/com/android/server/art/IArtd.aidl b/artd/binder/com/android/server/art/IArtd.aidl
index 74403485d5..ec57bd451b 100644
--- a/artd/binder/com/android/server/art/IArtd.aidl
+++ b/artd/binder/com/android/server/art/IArtd.aidl
@@ -177,4 +177,17 @@ interface IArtd {
* Throws fatal and non-fatal errors.
*/
boolean isInDalvikCache(@utf8InCpp String dexFile);
+
+ /**
+ * Returns an error message if the given dex path is invalid, or null if the validation
+ * passes.
+ */
+ @nullable @utf8InCpp String validateDexPath(@utf8InCpp String dexPath);
+
+ /**
+ * Returns an error message if the given class loader context is invalid, or null if the
+ * validation passes.
+ */
+ @nullable @utf8InCpp String validateClassLoaderContext(@utf8InCpp String dexPath,
+ @utf8InCpp String classLoaderContext);
}