diff options
author | 2023-08-14 11:08:03 +0100 | |
---|---|---|
committer | 2023-10-10 19:01:06 +0000 | |
commit | 8d5f52e883f25c2bba17b74b58cac43851a7fb23 (patch) | |
tree | f61f58882cd67c6c4e2443ce3fb4dff66ac5d6ca /artd | |
parent | 07b3996128bcc5f6cdc6421f72d89c12cbdabd7a (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.cc | 38 | ||||
-rw-r--r-- | artd/artd.h | 7 | ||||
-rw-r--r-- | artd/binder/com/android/server/art/IArtd.aidl | 13 |
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); } |