1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_ARTD_ARTD_H_ 18 #define ART_ARTD_ARTD_H_ 19 20 #include <sys/inotify.h> 21 #include <sys/mount.h> 22 #include <sys/poll.h> 23 #include <sys/stat.h> 24 #include <sys/types.h> 25 26 #include <csignal> 27 #include <cstdint> 28 #include <functional> 29 #include <memory> 30 #include <mutex> 31 #include <optional> 32 #include <string> 33 #include <unordered_map> 34 #include <unordered_set> 35 #include <utility> 36 #include <vector> 37 38 #include "aidl/com/android/server/art/BnArtd.h" 39 #include "aidl/com/android/server/art/BnArtdCancellationSignal.h" 40 #include "aidl/com/android/server/art/BnArtdNotification.h" 41 #include "aidl/com/android/server/art/SecureDexMetadataWithCompanionPaths.h" 42 #include "android-base/result.h" 43 #include "android-base/thread_annotations.h" 44 #include "android-base/unique_fd.h" 45 #include "android/binder_auto_utils.h" 46 #include "base/os.h" 47 #include "base/pidfd.h" 48 #include "exec_utils.h" 49 #include "oat/oat_file_assistant_context.h" 50 #include "tools/cmdline_builder.h" 51 #include "tools/system_properties.h" 52 53 namespace art { 54 namespace artd { 55 56 // Define these function types instead of getting them from C headers because those from glibc C 57 // headers contain the unwanted `noexcept`. 58 using KillFn = int(pid_t, int); 59 using FstatFn = int(int, struct stat*); 60 using PollFn = int(struct pollfd*, nfds_t, int); 61 using MountFn = int(const char*, const char*, const char*, uint32_t, const void*); 62 63 android::base::Result<void> Restorecon( 64 const std::string& path, 65 const std::optional< 66 aidl::com::android::server::art::OutputArtifacts::PermissionSettings::SeContext>& 67 se_context, 68 bool recurse); 69 70 struct Options { 71 // If true, this artd instance is for Pre-reboot Dexopt. It runs in a chroot environment that is 72 // set up by dexopt_chroot_setup. 73 bool is_pre_reboot = false; 74 }; 75 76 class ArtdCancellationSignal : public aidl::com::android::server::art::BnArtdCancellationSignal { 77 public: ArtdCancellationSignal(std::function<KillFn> kill_func)78 explicit ArtdCancellationSignal(std::function<KillFn> kill_func) : kill_(std::move(kill_func)) {} 79 80 ndk::ScopedAStatus cancel() override; 81 82 ndk::ScopedAStatus getType(int64_t* _aidl_return) override; 83 84 // Returns callbacks to be provided to `ExecUtils`, to register/unregister the process with this 85 // cancellation signal. 86 ExecCallbacks CreateExecCallbacks(); 87 88 bool IsCancelled(); 89 90 private: 91 std::mutex mu_; 92 // True if cancellation has been signaled. 93 bool is_cancelled_ GUARDED_BY(mu_) = false; 94 // The pids of currently running child processes that are bound to this signal. 95 std::unordered_set<pid_t> pids_ GUARDED_BY(mu_); 96 97 std::function<KillFn> kill_; 98 }; 99 100 class ArtdNotification : public aidl::com::android::server::art::BnArtdNotification { 101 public: ArtdNotification()102 ArtdNotification() : done_(true) {} ArtdNotification(std::function<PollFn> poll_func,const std::string & path,android::base::unique_fd && inotify_fd,android::base::unique_fd && pidfd)103 ArtdNotification(std::function<PollFn> poll_func, 104 const std::string& path, 105 android::base::unique_fd&& inotify_fd, 106 android::base::unique_fd&& pidfd) 107 : poll_(poll_func), 108 path_(std::move(path)), 109 inotify_fd_(std::move(inotify_fd)), 110 pidfd_(std::move(pidfd)), 111 done_(false) {} 112 113 ndk::ScopedAStatus wait(int in_timeoutMs, bool* _aidl_return) EXCLUDES(mu_) override; 114 115 virtual ~ArtdNotification(); 116 117 private: 118 void CleanUp() EXCLUDES(mu_); 119 120 const std::function<PollFn> poll_; 121 122 std::mutex mu_; 123 std::string path_ GUARDED_BY(mu_); 124 android::base::unique_fd inotify_fd_ GUARDED_BY(mu_); 125 android::base::unique_fd pidfd_ GUARDED_BY(mu_); 126 bool done_ GUARDED_BY(mu_); 127 bool is_called_ GUARDED_BY(mu_) = false; 128 }; 129 130 class Artd : public aidl::com::android::server::art::BnArtd { 131 public: 132 explicit Artd(Options&& options, 133 std::unique_ptr<art::tools::SystemProperties> props = 134 std::make_unique<art::tools::SystemProperties>(), 135 std::unique_ptr<ExecUtils> exec_utils = std::make_unique<ExecUtils>(), 136 std::function<KillFn> kill_func = kill, 137 std::function<FstatFn> fstat_func = fstat, 138 std::function<PollFn> poll_func = poll, 139 std::function<MountFn> mount_func = mount, 140 std::function<decltype(Restorecon)> restorecon_func = Restorecon, 141 std::optional<std::string> pre_reboot_tmp_dir = std::nullopt, 142 std::optional<std::string> init_environ_rc_path = std::nullopt, 143 std::unique_ptr<art::tools::SystemProperties> pre_reboot_build_props = nullptr) options_(std::move (options))144 : options_(std::move(options)), 145 props_(std::move(props)), 146 exec_utils_(std::move(exec_utils)), 147 kill_(std::move(kill_func)), 148 fstat_(std::move(fstat_func)), 149 poll_(std::move(poll_func)), 150 mount_(std::move(mount_func)), 151 restorecon_(std::move(restorecon_func)), 152 pre_reboot_tmp_dir_(std::move(pre_reboot_tmp_dir)), 153 init_environ_rc_path_(std::move(init_environ_rc_path)), 154 pre_reboot_build_props_(std::move(pre_reboot_build_props)) {} 155 156 ndk::ScopedAStatus isAlive(bool* _aidl_return) override; 157 158 ndk::ScopedAStatus deleteArtifacts( 159 const aidl::com::android::server::art::ArtifactsPath& in_artifactsPath, 160 int64_t* _aidl_return) override; 161 162 ndk::ScopedAStatus getDexoptStatus( 163 const std::string& in_dexFile, 164 const std::string& in_instructionSet, 165 const std::optional<std::string>& in_classLoaderContext, 166 aidl::com::android::server::art::GetDexoptStatusResult* _aidl_return) override; 167 168 ndk::ScopedAStatus isProfileUsable(const aidl::com::android::server::art::ProfilePath& in_profile, 169 const std::string& in_dexFile, 170 bool* _aidl_return) override; 171 172 ndk::ScopedAStatus copyAndRewriteProfile( 173 const aidl::com::android::server::art::ProfilePath& in_src, 174 aidl::com::android::server::art::OutputProfile* in_dst, 175 const std::string& in_dexFile, 176 aidl::com::android::server::art::CopyAndRewriteProfileResult* _aidl_return) override; 177 178 ndk::ScopedAStatus copyAndRewriteEmbeddedProfile( 179 aidl::com::android::server::art::OutputProfile* in_dst, 180 const std::string& in_dexFile, 181 aidl::com::android::server::art::CopyAndRewriteProfileResult* _aidl_return) override; 182 183 ndk::ScopedAStatus commitTmpProfile( 184 const aidl::com::android::server::art::ProfilePath::TmpProfilePath& in_profile) override; 185 186 ndk::ScopedAStatus deleteProfile( 187 const aidl::com::android::server::art::ProfilePath& in_profile) override; 188 189 ndk::ScopedAStatus getProfileVisibility( 190 const aidl::com::android::server::art::ProfilePath& in_profile, 191 aidl::com::android::server::art::FileVisibility* _aidl_return) override; 192 193 ndk::ScopedAStatus mergeProfiles( 194 const std::vector<aidl::com::android::server::art::ProfilePath>& in_profiles, 195 const std::optional<aidl::com::android::server::art::ProfilePath>& in_referenceProfile, 196 aidl::com::android::server::art::OutputProfile* in_outputProfile, 197 const std::vector<std::string>& in_dexFiles, 198 const aidl::com::android::server::art::MergeProfileOptions& in_options, 199 bool* _aidl_return) override; 200 201 ndk::ScopedAStatus getArtifactsVisibility( 202 const aidl::com::android::server::art::ArtifactsPath& in_artifactsPath, 203 aidl::com::android::server::art::FileVisibility* _aidl_return) override; 204 205 ndk::ScopedAStatus getDexFileVisibility( 206 const std::string& in_dexFile, 207 aidl::com::android::server::art::FileVisibility* _aidl_return) override; 208 209 ndk::ScopedAStatus getDmFileVisibility( 210 const aidl::com::android::server::art::DexMetadataPath& in_dmFile, 211 aidl::com::android::server::art::FileVisibility* _aidl_return) override; 212 213 ndk::ScopedAStatus getDexoptNeeded( 214 const std::string& in_dexFile, 215 const std::string& in_instructionSet, 216 const std::optional<std::string>& in_classLoaderContext, 217 const std::string& in_compilerFilter, 218 int32_t in_dexoptTrigger, 219 aidl::com::android::server::art::GetDexoptNeededResult* _aidl_return) override; 220 221 ndk::ScopedAStatus maybeCreateSdc( 222 const aidl::com::android::server::art::OutputSecureDexMetadataCompanion& in_outputSdc) 223 override; 224 225 ndk::ScopedAStatus dexopt( 226 const aidl::com::android::server::art::OutputArtifacts& in_outputArtifacts, 227 const std::string& in_dexFile, 228 const std::string& in_instructionSet, 229 const std::optional<std::string>& in_classLoaderContext, 230 const std::string& in_compilerFilter, 231 const std::optional<aidl::com::android::server::art::ProfilePath>& in_profile, 232 const std::optional<aidl::com::android::server::art::VdexPath>& in_inputVdex, 233 const std::optional<aidl::com::android::server::art::DexMetadataPath>& in_dmFile, 234 aidl::com::android::server::art::PriorityClass in_priorityClass, 235 const aidl::com::android::server::art::DexoptOptions& in_dexoptOptions, 236 const std::shared_ptr<aidl::com::android::server::art::IArtdCancellationSignal>& 237 in_cancellationSignal, 238 aidl::com::android::server::art::ArtdDexoptResult* _aidl_return) override; 239 240 ndk::ScopedAStatus createCancellationSignal( 241 std::shared_ptr<aidl::com::android::server::art::IArtdCancellationSignal>* _aidl_return) 242 override; 243 244 ndk::ScopedAStatus cleanup( 245 const std::vector<aidl::com::android::server::art::ProfilePath>& in_profilesToKeep, 246 const std::vector<aidl::com::android::server::art::ArtifactsPath>& in_artifactsToKeep, 247 const std::vector<aidl::com::android::server::art::VdexPath>& in_vdexFilesToKeep, 248 const std::vector<aidl::com::android::server::art::SecureDexMetadataWithCompanionPaths>& 249 in_SdmSdcFilesToKeep, 250 const std::vector<aidl::com::android::server::art::RuntimeArtifactsPath>& 251 in_runtimeArtifactsToKeep, 252 bool in_keepPreRebootStagedFiles, 253 int64_t* _aidl_return) override; 254 255 ndk::ScopedAStatus cleanUpPreRebootStagedFiles() override; 256 257 ndk::ScopedAStatus isInDalvikCache(const std::string& in_dexFile, bool* _aidl_return) override; 258 259 ndk::ScopedAStatus deleteSdmSdcFiles( 260 const aidl::com::android::server::art::SecureDexMetadataWithCompanionPaths& in_sdmSdcPaths, 261 int64_t* _aidl_return) override; 262 263 ndk::ScopedAStatus deleteRuntimeArtifacts( 264 const aidl::com::android::server::art::RuntimeArtifactsPath& in_runtimeArtifactsPath, 265 int64_t* _aidl_return) override; 266 267 ndk::ScopedAStatus getArtifactsSize( 268 const aidl::com::android::server::art::ArtifactsPath& in_artifactsPath, 269 int64_t* _aidl_return) override; 270 271 ndk::ScopedAStatus getVdexFileSize(const aidl::com::android::server::art::VdexPath& in_vdexPath, 272 int64_t* _aidl_return) override; 273 274 ndk::ScopedAStatus getSdmFileSize( 275 const aidl::com::android::server::art::SecureDexMetadataWithCompanionPaths& in_sdmPath, 276 int64_t* _aidl_return) override; 277 278 ndk::ScopedAStatus getRuntimeArtifactsSize( 279 const aidl::com::android::server::art::RuntimeArtifactsPath& in_runtimeArtifactsPath, 280 int64_t* _aidl_return) override; 281 282 ndk::ScopedAStatus getProfileSize(const aidl::com::android::server::art::ProfilePath& in_profile, 283 int64_t* _aidl_return) override; 284 285 ndk::ScopedAStatus initProfileSaveNotification( 286 const aidl::com::android::server::art::ProfilePath::PrimaryCurProfilePath& in_profilePath, 287 int in_pid, 288 std::shared_ptr<aidl::com::android::server::art::IArtdNotification>* _aidl_return) override; 289 290 ndk::ScopedAStatus commitPreRebootStagedFiles( 291 const std::vector<aidl::com::android::server::art::ArtifactsPath>& in_artifacts, 292 const std::vector<aidl::com::android::server::art::ProfilePath::WritableProfilePath>& 293 in_profiles, 294 bool* _aidl_return) override; 295 296 ndk::ScopedAStatus checkPreRebootSystemRequirements(const std::string& in_chrootDir, 297 bool* _aidl_return) override; 298 299 ndk::ScopedAStatus preRebootInit( 300 const std::shared_ptr<aidl::com::android::server::art::IArtdCancellationSignal>& 301 in_cancellationSignal, 302 bool* _aidl_return) override; 303 304 ndk::ScopedAStatus validateDexPath(const std::string& in_dexFile, 305 std::optional<std::string>* _aidl_return) override; 306 307 ndk::ScopedAStatus validateClassLoaderContext(const std::string& in_dexFile, 308 const std::string& in_classLoaderContext, 309 std::optional<std::string>* _aidl_return) override; 310 311 android::base::Result<void> Start(); 312 313 private: 314 android::base::Result<OatFileAssistantContext*> GetOatFileAssistantContext() 315 EXCLUDES(ofa_context_mu_); 316 317 android::base::Result<const std::vector<std::string>*> GetBootImageLocations() 318 EXCLUDES(cache_mu_); 319 320 android::base::Result<const std::vector<std::string>*> GetBootClassPath() EXCLUDES(cache_mu_); 321 322 bool UseJitZygote() EXCLUDES(cache_mu_); 323 bool UseJitZygoteLocked() REQUIRES(cache_mu_); 324 325 const std::string& GetUserDefinedBootImageLocations() EXCLUDES(cache_mu_); 326 const std::string& GetUserDefinedBootImageLocationsLocked() REQUIRES(cache_mu_); 327 328 bool DenyArtApexDataFiles() EXCLUDES(cache_mu_); 329 bool DenyArtApexDataFilesLocked() REQUIRES(cache_mu_); 330 331 android::base::Result<int> ExecAndReturnCode(const std::vector<std::string>& arg_vector, 332 int timeout_sec, 333 const ExecCallbacks& callbacks = ExecCallbacks(), 334 ProcessStat* stat = nullptr) const; 335 336 android::base::Result<std::string> GetProfman(); 337 338 android::base::Result<tools::CmdlineBuilder> GetArtExecCmdlineBuilder(); 339 340 bool ShouldUseDex2Oat64(); 341 342 bool ShouldUseDebugBinaries(); 343 344 android::base::Result<std::string> GetDex2Oat(); 345 346 bool ShouldCreateSwapFileForDexopt(); 347 348 void AddBootImageFlags(/*out*/ art::tools::CmdlineBuilder& args); 349 350 void AddCompilerConfigFlags(const std::string& instruction_set, 351 const std::string& compiler_filter, 352 const aidl::com::android::server::art::DexoptOptions& dexopt_options, 353 /*out*/ art::tools::CmdlineBuilder& args); 354 355 void AddPerfConfigFlags(aidl::com::android::server::art::PriorityClass priority_class, 356 /*out*/ art::tools::CmdlineBuilder& art_exec_args, 357 /*out*/ art::tools::CmdlineBuilder& args); 358 359 android::base::Result<struct stat> Fstat(const art::File& file) const; 360 361 // Creates a new dir at `source` and bind-mounts it at `target`. 362 android::base::Result<void> BindMountNewDir(const std::string& source, 363 const std::string& target) const; 364 365 android::base::Result<void> BindMount(const std::string& source, const std::string& target) const; 366 367 ndk::ScopedAStatus CopyAndRewriteProfileImpl( 368 File src, 369 aidl::com::android::server::art::OutputProfile* dst_aidl, 370 const std::string& dex_path, 371 aidl::com::android::server::art::CopyAndRewriteProfileResult* aidl_return); 372 373 android::base::Result<void> PreRebootInitClearEnvs(); 374 android::base::Result<void> PreRebootInitSetEnvFromFile(const std::string& path); 375 android::base::Result<void> PreRebootInitDeriveClasspath(const std::string& path); 376 android::base::Result<bool> PreRebootInitBootImages(ArtdCancellationSignal* cancellation_signal); 377 378 std::mutex cache_mu_; 379 std::optional<std::vector<std::string>> cached_boot_image_locations_ GUARDED_BY(cache_mu_); 380 std::optional<std::vector<std::string>> cached_boot_class_path_ GUARDED_BY(cache_mu_); 381 std::optional<bool> cached_use_jit_zygote_ GUARDED_BY(cache_mu_); 382 std::optional<std::string> cached_user_defined_boot_image_locations_ GUARDED_BY(cache_mu_); 383 std::optional<bool> cached_deny_art_apex_data_files_ GUARDED_BY(cache_mu_); 384 385 std::mutex ofa_context_mu_; 386 std::unique_ptr<OatFileAssistantContext> ofa_context_ GUARDED_BY(ofa_context_mu_); 387 388 const Options options_; 389 const std::unique_ptr<art::tools::SystemProperties> props_; 390 const std::unique_ptr<ExecUtils> exec_utils_; 391 const std::function<KillFn> kill_; 392 const std::function<FstatFn> fstat_; 393 const std::function<PollFn> poll_; 394 const std::function<MountFn> mount_; 395 const std::function<decltype(Restorecon)> restorecon_; 396 const std::optional<std::string> pre_reboot_tmp_dir_; 397 const std::optional<std::string> init_environ_rc_path_; 398 std::unique_ptr<art::tools::SystemProperties> pre_reboot_build_props_; 399 }; 400 401 // A class for getting system properties from a `build.prop` file. 402 // Note that this class ignores import statements and only reads properties from the given file 403 // itself. To read properties from an imported file, insatiate this class with the imported file 404 // directly. 405 class BuildSystemProperties : public tools::SystemProperties { 406 public: 407 // Creates an instance and loads system properties from the `build.prop` file specified at the 408 // given path. 409 static android::base::Result<BuildSystemProperties> Create(const std::string& filename); 410 411 protected: 412 std::string GetProperty(const std::string& key) const override; 413 414 private: BuildSystemProperties(std::unordered_map<std::string,std::string> && system_properties)415 explicit BuildSystemProperties(std::unordered_map<std::string, std::string>&& system_properties) 416 : system_properties_(std::move(system_properties)) {} 417 418 const std::unordered_map<std::string, std::string> system_properties_; 419 }; 420 421 } // namespace artd 422 } // namespace art 423 424 #endif // ART_ARTD_ARTD_H_ 425