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