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 #include "path_utils.h"
18
19 #include <filesystem>
20 #include <string>
21 #include <vector>
22
23 #include "aidl/com/android/server/art/ArtConstants.h"
24 #include "aidl/com/android/server/art/BnArtd.h"
25 #include "android-base/errors.h"
26 #include "android-base/result.h"
27 #include "arch/instruction_set.h"
28 #include "base/file_utils.h"
29 #include "base/macros.h"
30 #include "file_utils.h"
31 #include "oat/oat_file_assistant.h"
32 #include "runtime_image.h"
33 #include "service.h"
34 #include "tools/tools.h"
35
36 namespace art {
37 namespace artd {
38
39 namespace {
40
41 using ::aidl::com::android::server::art::ArtConstants;
42 using ::aidl::com::android::server::art::ArtifactsPath;
43 using ::aidl::com::android::server::art::DexMetadataPath;
44 using ::aidl::com::android::server::art::OutputArtifacts;
45 using ::aidl::com::android::server::art::OutputProfile;
46 using ::aidl::com::android::server::art::ProfilePath;
47 using ::aidl::com::android::server::art::RuntimeArtifactsPath;
48 using ::aidl::com::android::server::art::VdexPath;
49 using ::android::base::Error;
50 using ::android::base::Result;
51 using ::art::service::ValidateDexPath;
52 using ::art::service::ValidatePathElement;
53 using ::art::service::ValidatePathElementSubstring;
54
55 using PrebuiltProfilePath = ProfilePath::PrebuiltProfilePath;
56 using PrimaryCurProfilePath = ProfilePath::PrimaryCurProfilePath;
57 using PrimaryRefProfilePath = ProfilePath::PrimaryRefProfilePath;
58 using SecondaryCurProfilePath = ProfilePath::SecondaryCurProfilePath;
59 using SecondaryRefProfilePath = ProfilePath::SecondaryRefProfilePath;
60 using TmpProfilePath = ProfilePath::TmpProfilePath;
61 using WritableProfilePath = ProfilePath::WritableProfilePath;
62
63 constexpr const char* kPreRebootSuffix = ".staged";
64
65 // Only to be changed for testing.
66 std::string_view gListRootDir = "/";
67
68 } // namespace
69
GetAndroidDataOrError()70 Result<std::string> GetAndroidDataOrError() {
71 std::string error_msg;
72 std::string result = GetAndroidDataSafe(&error_msg);
73 if (!error_msg.empty()) {
74 return Error() << error_msg;
75 }
76 return result;
77 }
78
GetAndroidExpandOrError()79 Result<std::string> GetAndroidExpandOrError() {
80 std::string error_msg;
81 std::string result = GetAndroidExpandSafe(&error_msg);
82 if (!error_msg.empty()) {
83 return Error() << error_msg;
84 }
85 return result;
86 }
87
GetArtRootOrError()88 Result<std::string> GetArtRootOrError() {
89 std::string error_msg;
90 std::string result = GetArtRootSafe(&error_msg);
91 if (!error_msg.empty()) {
92 return Error() << error_msg;
93 }
94 return result;
95 }
96
ListManagedFiles(const std::string & android_data,const std::string & android_expand)97 std::vector<std::string> ListManagedFiles(const std::string& android_data,
98 const std::string& android_expand) {
99 // See `art::tools::Glob` for the syntax.
100 std::vector<std::string> patterns = {
101 // Profiles for primary dex files.
102 android_data + "/misc/profiles/**",
103 // Artifacts for primary dex files.
104 android_data + "/dalvik-cache/**",
105 };
106
107 for (const std::string& data_root : {android_data, android_expand + "/*"}) {
108 // Artifacts for primary dex files.
109 patterns.push_back(data_root + "/app/*/*/oat/**");
110
111 for (const char* user_dir : {"/user", "/user_de"}) {
112 std::string data_dir = data_root + user_dir + "/*/*";
113 // Profiles and artifacts for secondary dex files. Those files are in app data directories, so
114 // we use more granular patterns to avoid accidentally deleting apps' files.
115 std::string secondary_oat_dir = data_dir + "/**/oat";
116 for (const char* suffix : {"", ".*.tmp", kPreRebootSuffix}) {
117 patterns.push_back(secondary_oat_dir + "/*" + ArtConstants::PROFILE_FILE_EXT + suffix);
118 patterns.push_back(secondary_oat_dir + "/*/*" + kOdexExtension + suffix);
119 patterns.push_back(secondary_oat_dir + "/*/*" + kVdexExtension + suffix);
120 patterns.push_back(secondary_oat_dir + "/*/*" + kArtExtension + suffix);
121 }
122 // Runtime image files.
123 patterns.push_back(RuntimeImage::GetRuntimeImageDir(data_dir) + "**");
124 }
125 }
126
127 return tools::Glob(patterns, gListRootDir);
128 }
129
ListRuntimeArtifactsFiles(const std::string & android_data,const std::string & android_expand,const RuntimeArtifactsPath & runtime_artifacts_path)130 std::vector<std::string> ListRuntimeArtifactsFiles(
131 const std::string& android_data,
132 const std::string& android_expand,
133 const RuntimeArtifactsPath& runtime_artifacts_path) {
134 // See `art::tools::Glob` for the syntax.
135 std::vector<std::string> patterns;
136
137 for (const std::string& data_root : {android_data, android_expand + "/*"}) {
138 for (const char* user_dir : {"/user", "/user_de"}) {
139 std::string data_dir =
140 data_root + user_dir + "/*/" + tools::EscapeGlob(runtime_artifacts_path.packageName);
141 patterns.push_back(
142 RuntimeImage::GetRuntimeImagePath(data_dir,
143 tools::EscapeGlob(runtime_artifacts_path.dexPath),
144 tools::EscapeGlob(runtime_artifacts_path.isa)));
145 }
146 }
147
148 return tools::Glob(patterns, gListRootDir);
149 }
150
ValidateRuntimeArtifactsPath(const RuntimeArtifactsPath & runtime_artifacts_path)151 Result<void> ValidateRuntimeArtifactsPath(const RuntimeArtifactsPath& runtime_artifacts_path) {
152 OR_RETURN(ValidatePathElement(runtime_artifacts_path.packageName, "packageName"));
153 OR_RETURN(ValidatePathElement(runtime_artifacts_path.isa, "isa"));
154 OR_RETURN(ValidateDexPath(runtime_artifacts_path.dexPath));
155 return {};
156 }
157
BuildArtBinPath(const std::string & binary_name)158 Result<std::string> BuildArtBinPath(const std::string& binary_name) {
159 return ART_FORMAT("{}/bin/{}", OR_RETURN(GetArtRootOrError()), binary_name);
160 }
161
BuildArtifactsPath(const ArtifactsPath & artifacts_path)162 Result<RawArtifactsPath> BuildArtifactsPath(const ArtifactsPath& artifacts_path) {
163 OR_RETURN(ValidateDexPath(artifacts_path.dexPath));
164
165 InstructionSet isa = GetInstructionSetFromString(artifacts_path.isa.c_str());
166 if (isa == InstructionSet::kNone) {
167 return Errorf("Instruction set '{}' is invalid", artifacts_path.isa);
168 }
169
170 std::string error_msg;
171 RawArtifactsPath path;
172 if (artifacts_path.isInDalvikCache) {
173 // Apps' OAT files are never in ART APEX data.
174 if (!OatFileAssistant::DexLocationToOatFilename(artifacts_path.dexPath,
175 isa,
176 /*deny_art_apex_data_files=*/true,
177 &path.oat_path,
178 &error_msg)) {
179 return Error() << error_msg;
180 }
181 } else {
182 if (!OatFileAssistant::DexLocationToOdexFilename(
183 artifacts_path.dexPath, isa, &path.oat_path, &error_msg)) {
184 return Error() << error_msg;
185 }
186 }
187
188 path.vdex_path = ReplaceFileExtension(path.oat_path, kVdexExtension);
189 path.art_path = ReplaceFileExtension(path.oat_path, kArtExtension);
190
191 if (artifacts_path.isPreReboot) {
192 path.oat_path += kPreRebootSuffix;
193 path.vdex_path += kPreRebootSuffix;
194 path.art_path += kPreRebootSuffix;
195 }
196
197 return path;
198 }
199
BuildPrimaryRefProfilePath(const PrimaryRefProfilePath & primary_ref_profile_path)200 Result<std::string> BuildPrimaryRefProfilePath(
201 const PrimaryRefProfilePath& primary_ref_profile_path) {
202 OR_RETURN(ValidatePathElement(primary_ref_profile_path.packageName, "packageName"));
203 OR_RETURN(ValidatePathElementSubstring(primary_ref_profile_path.profileName, "profileName"));
204 return ART_FORMAT("{}/misc/profiles/ref/{}/{}{}{}",
205 OR_RETURN(GetAndroidDataOrError()),
206 primary_ref_profile_path.packageName,
207 primary_ref_profile_path.profileName,
208 ArtConstants::PROFILE_FILE_EXT,
209 primary_ref_profile_path.isPreReboot ? kPreRebootSuffix : "");
210 }
211
BuildPrebuiltProfilePath(const PrebuiltProfilePath & prebuilt_profile_path)212 Result<std::string> BuildPrebuiltProfilePath(const PrebuiltProfilePath& prebuilt_profile_path) {
213 OR_RETURN(ValidateDexPath(prebuilt_profile_path.dexPath));
214 return prebuilt_profile_path.dexPath + ArtConstants::PROFILE_FILE_EXT;
215 }
216
BuildPrimaryCurProfilePath(const PrimaryCurProfilePath & primary_cur_profile_path)217 Result<std::string> BuildPrimaryCurProfilePath(
218 const PrimaryCurProfilePath& primary_cur_profile_path) {
219 OR_RETURN(ValidatePathElement(primary_cur_profile_path.packageName, "packageName"));
220 OR_RETURN(ValidatePathElementSubstring(primary_cur_profile_path.profileName, "profileName"));
221 return ART_FORMAT("{}/misc/profiles/cur/{}/{}/{}{}",
222 OR_RETURN(GetAndroidDataOrError()),
223 primary_cur_profile_path.userId,
224 primary_cur_profile_path.packageName,
225 primary_cur_profile_path.profileName,
226 ArtConstants::PROFILE_FILE_EXT);
227 }
228
BuildSecondaryRefProfilePath(const SecondaryRefProfilePath & secondary_ref_profile_path)229 Result<std::string> BuildSecondaryRefProfilePath(
230 const SecondaryRefProfilePath& secondary_ref_profile_path) {
231 OR_RETURN(ValidateDexPath(secondary_ref_profile_path.dexPath));
232 std::filesystem::path dex_path(secondary_ref_profile_path.dexPath);
233 return ART_FORMAT("{}/oat/{}{}{}",
234 dex_path.parent_path().string(),
235 dex_path.filename().string(),
236 ArtConstants::PROFILE_FILE_EXT,
237 secondary_ref_profile_path.isPreReboot ? kPreRebootSuffix : "");
238 }
239
BuildSecondaryCurProfilePath(const SecondaryCurProfilePath & secondary_cur_profile_path)240 Result<std::string> BuildSecondaryCurProfilePath(
241 const SecondaryCurProfilePath& secondary_cur_profile_path) {
242 OR_RETURN(ValidateDexPath(secondary_cur_profile_path.dexPath));
243 std::filesystem::path dex_path(secondary_cur_profile_path.dexPath);
244 return ART_FORMAT("{}/oat/{}.cur{}",
245 dex_path.parent_path().string(),
246 dex_path.filename().string(),
247 ArtConstants::PROFILE_FILE_EXT);
248 }
249
BuildWritableProfilePath(const WritableProfilePath & profile_path)250 Result<std::string> BuildWritableProfilePath(const WritableProfilePath& profile_path) {
251 switch (profile_path.getTag()) {
252 case WritableProfilePath::forPrimary:
253 return BuildPrimaryRefProfilePath(profile_path.get<WritableProfilePath::forPrimary>());
254 case WritableProfilePath::forSecondary:
255 return BuildSecondaryRefProfilePath(profile_path.get<WritableProfilePath::forSecondary>());
256 // No default. All cases should be explicitly handled, or the compilation will fail.
257 }
258 // This should never happen. Just in case we get a non-enumerator value.
259 LOG(FATAL) << ART_FORMAT("Unexpected writable profile path type {}",
260 fmt::underlying(profile_path.getTag()));
261 }
262
BuildFinalProfilePath(const TmpProfilePath & tmp_profile_path)263 Result<std::string> BuildFinalProfilePath(const TmpProfilePath& tmp_profile_path) {
264 return BuildWritableProfilePath(tmp_profile_path.finalPath);
265 }
266
BuildTmpProfilePath(const TmpProfilePath & tmp_profile_path)267 Result<std::string> BuildTmpProfilePath(const TmpProfilePath& tmp_profile_path) {
268 OR_RETURN(ValidatePathElementSubstring(tmp_profile_path.id, "id"));
269 return NewFile::BuildTempPath(OR_RETURN(BuildFinalProfilePath(tmp_profile_path)),
270 tmp_profile_path.id);
271 }
272
BuildDexMetadataPath(const DexMetadataPath & dex_metadata_path)273 Result<std::string> BuildDexMetadataPath(const DexMetadataPath& dex_metadata_path) {
274 OR_RETURN(ValidateDexPath(dex_metadata_path.dexPath));
275 return ReplaceFileExtension(dex_metadata_path.dexPath, kDmExtension);
276 }
277
BuildProfileOrDmPath(const ProfilePath & profile_path)278 Result<std::string> BuildProfileOrDmPath(const ProfilePath& profile_path) {
279 switch (profile_path.getTag()) {
280 case ProfilePath::primaryRefProfilePath:
281 return BuildPrimaryRefProfilePath(profile_path.get<ProfilePath::primaryRefProfilePath>());
282 case ProfilePath::prebuiltProfilePath:
283 return BuildPrebuiltProfilePath(profile_path.get<ProfilePath::prebuiltProfilePath>());
284 case ProfilePath::primaryCurProfilePath:
285 return BuildPrimaryCurProfilePath(profile_path.get<ProfilePath::primaryCurProfilePath>());
286 case ProfilePath::secondaryRefProfilePath:
287 return BuildSecondaryRefProfilePath(profile_path.get<ProfilePath::secondaryRefProfilePath>());
288 case ProfilePath::secondaryCurProfilePath:
289 return BuildSecondaryCurProfilePath(profile_path.get<ProfilePath::secondaryCurProfilePath>());
290 case ProfilePath::tmpProfilePath:
291 return BuildTmpProfilePath(profile_path.get<ProfilePath::tmpProfilePath>());
292 case ProfilePath::dexMetadataPath:
293 return BuildDexMetadataPath(profile_path.get<ProfilePath::dexMetadataPath>());
294 // No default. All cases should be explicitly handled, or the compilation will fail.
295 }
296 // This should never happen. Just in case we get a non-enumerator value.
297 LOG(FATAL) << ART_FORMAT("Unexpected profile path type {}",
298 fmt::underlying(profile_path.getTag()));
299 }
300
BuildVdexPath(const VdexPath & vdex_path)301 Result<std::string> BuildVdexPath(const VdexPath& vdex_path) {
302 DCHECK(vdex_path.getTag() == VdexPath::artifactsPath);
303 return OR_RETURN(BuildArtifactsPath(vdex_path.get<VdexPath::artifactsPath>())).vdex_path;
304 }
305
PreRebootFlag(const ProfilePath & profile_path)306 bool PreRebootFlag(const ProfilePath& profile_path) {
307 switch (profile_path.getTag()) {
308 case ProfilePath::primaryRefProfilePath:
309 return profile_path.get<ProfilePath::primaryRefProfilePath>().isPreReboot;
310 case ProfilePath::secondaryRefProfilePath:
311 return profile_path.get<ProfilePath::secondaryRefProfilePath>().isPreReboot;
312 case ProfilePath::tmpProfilePath:
313 return PreRebootFlag(profile_path.get<ProfilePath::tmpProfilePath>());
314 case ProfilePath::prebuiltProfilePath:
315 case ProfilePath::primaryCurProfilePath:
316 case ProfilePath::secondaryCurProfilePath:
317 case ProfilePath::dexMetadataPath:
318 return false;
319 // No default. All cases should be explicitly handled, or the compilation will fail.
320 }
321 // This should never happen. Just in case we get a non-enumerator value.
322 LOG(FATAL) << ART_FORMAT("Unexpected profile path type {}",
323 fmt::underlying(profile_path.getTag()));
324 }
325
PreRebootFlag(const TmpProfilePath & tmp_profile_path)326 bool PreRebootFlag(const TmpProfilePath& tmp_profile_path) {
327 return PreRebootFlag(tmp_profile_path.finalPath);
328 }
329
PreRebootFlag(const OutputProfile & profile)330 bool PreRebootFlag(const OutputProfile& profile) { return PreRebootFlag(profile.profilePath); }
331
PreRebootFlag(const ArtifactsPath & artifacts_path)332 bool PreRebootFlag(const ArtifactsPath& artifacts_path) { return artifacts_path.isPreReboot; }
333
PreRebootFlag(const OutputArtifacts & artifacts)334 bool PreRebootFlag(const OutputArtifacts& artifacts) {
335 return PreRebootFlag(artifacts.artifactsPath);
336 }
337
PreRebootFlag(const VdexPath & vdex_path)338 bool PreRebootFlag(const VdexPath& vdex_path) {
339 return PreRebootFlag(vdex_path.get<VdexPath::artifactsPath>());
340 }
341
IsPreRebootStagedFile(std::string_view filename)342 bool IsPreRebootStagedFile(std::string_view filename) {
343 return filename.ends_with(kPreRebootSuffix);
344 }
345
TestOnlySetListRootDir(std::string_view root_dir)346 void TestOnlySetListRootDir(std::string_view root_dir) { gListRootDir = root_dir; }
347
348 } // namespace artd
349 } // namespace art
350