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