From 8d5f52e883f25c2bba17b74b58cac43851a7fb23 Mon Sep 17 00:00:00 2001 From: Jiakai Zhang Date: Mon, 14 Aug 2023 11:08:03 +0100 Subject: 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 --- artd/artd.cc | 38 +++++++++++++++++++++++++++ artd/artd.h | 7 +++++ artd/binder/com/android/server/art/IArtd.aidl | 13 +++++++++ 3 files changed, 58 insertions(+) (limited to 'artd') 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* _aidl_return) { + if (Result 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* _aidl_return) { + if (in_classLoaderContext == ClassLoaderContext::kUnsupportedClassLoaderContextEncoding) { + *_aidl_return = std::nullopt; + return ScopedAStatus::ok(); + } + + std::unique_ptr context = ClassLoaderContext::Create(in_classLoaderContext); + if (context == nullptr) { + *_aidl_return = ART_FORMAT("Class loader context '{}' is invalid", in_classLoaderContext); + return ScopedAStatus::ok(); + } + + std::vector 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 result = ValidateDexPath(context_path); !result.ok()) { + *_aidl_return = result.error().message(); + return ScopedAStatus::ok(); + } + } + + *_aidl_return = std::nullopt; + return ScopedAStatus::ok(); +} + Result 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* _aidl_return) override; + + ndk::ScopedAStatus validateClassLoaderContext(const std::string& in_dexPath, + const std::string& in_classLoaderContext, + std::optional* _aidl_return) override; + android::base::Result 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); } -- cgit v1.2.3-59-g8ed1b