• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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