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