blob: 37f329000d4cbfcee989601e4c54a58671a48f48 [file] [log] [blame]
Jeff Sharkey6c2c0562016-12-07 12:12:00 -07001/*
2 * Copyright (C) 2016 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
Jeff Sharkey90aff262016-12-12 14:28:24 -070017#include <fcntl.h>
Jeff Sharkey6c2c0562016-12-07 12:12:00 -070018#include <stdlib.h>
19#include <string.h>
Jeff Sharkey90aff262016-12-12 14:28:24 -070020#include <sys/capability.h>
21#include <sys/file.h>
Jeff Sharkey6c2c0562016-12-07 12:12:00 -070022#include <sys/stat.h>
Jeff Sharkey90aff262016-12-12 14:28:24 -070023#include <sys/time.h>
24#include <sys/types.h>
25#include <sys/resource.h>
26#include <sys/wait.h>
Jeff Sharkey6c2c0562016-12-07 12:12:00 -070027#include <unistd.h>
28
29#include <android-base/logging.h>
30#include <android-base/stringprintf.h>
Jeff Sharkey90aff262016-12-12 14:28:24 -070031#include <android-base/strings.h>
32#include <android-base/unique_fd.h>
33#include <cutils/log.h> // TODO: Move everything to base/logging.
34#include <cutils/properties.h>
35#include <cutils/sched_policy.h>
36#include <private/android_filesystem_config.h>
37#include <system/thread_defs.h>
Jeff Sharkey6c2c0562016-12-07 12:12:00 -070038
39#include "dexopt.h"
Jeff Sharkey90aff262016-12-12 14:28:24 -070040#include "installd_deps.h"
41#include "otapreopt_utils.h"
Jeff Sharkey6c2c0562016-12-07 12:12:00 -070042#include "utils.h"
43
44using android::base::StringPrintf;
Jeff Sharkey90aff262016-12-12 14:28:24 -070045using android::base::EndsWith;
Jeff Sharkey6c2c0562016-12-07 12:12:00 -070046
47namespace android {
48namespace installd {
49
50static const char* parse_null(const char* arg) {
51 if (strcmp(arg, "!") == 0) {
52 return nullptr;
53 } else {
54 return arg;
55 }
56}
57
Jeff Sharkey90aff262016-12-12 14:28:24 -070058static bool clear_profile(const std::string& profile) {
59 base::unique_fd ufd(open(profile.c_str(), O_WRONLY | O_NOFOLLOW | O_CLOEXEC));
60 if (ufd.get() < 0) {
61 if (errno != ENOENT) {
62 PLOG(WARNING) << "Could not open profile " << profile;
63 return false;
64 } else {
65 // Nothing to clear. That's ok.
66 return true;
67 }
68 }
69
70 if (flock(ufd.get(), LOCK_EX | LOCK_NB) != 0) {
71 if (errno != EWOULDBLOCK) {
72 PLOG(WARNING) << "Error locking profile " << profile;
73 }
74 // This implies that the app owning this profile is running
75 // (and has acquired the lock).
76 //
77 // If we can't acquire the lock bail out since clearing is useless anyway
78 // (the app will write again to the profile).
79 //
80 // Note:
81 // This does not impact the this is not an issue for the profiling correctness.
82 // In case this is needed because of an app upgrade, profiles will still be
83 // eventually cleared by the app itself due to checksum mismatch.
84 // If this is needed because profman advised, then keeping the data around
85 // until the next run is again not an issue.
86 //
87 // If the app attempts to acquire a lock while we've held one here,
88 // it will simply skip the current write cycle.
89 return false;
90 }
91
92 bool truncated = ftruncate(ufd.get(), 0) == 0;
93 if (!truncated) {
94 PLOG(WARNING) << "Could not truncate " << profile;
95 }
96 if (flock(ufd.get(), LOCK_UN) != 0) {
97 PLOG(WARNING) << "Error unlocking profile " << profile;
98 }
99 return truncated;
100}
101
102bool clear_reference_profile(const char* pkgname) {
103 std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
104 std::string reference_profile = create_primary_profile(reference_profile_dir);
105 return clear_profile(reference_profile);
106}
107
108bool clear_current_profile(const char* pkgname, userid_t user) {
109 std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
110 std::string profile = create_primary_profile(profile_dir);
111 return clear_profile(profile);
112}
113
114bool clear_current_profiles(const char* pkgname) {
115 bool success = true;
116 std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
117 for (auto user : users) {
118 success &= clear_current_profile(pkgname, user);
119 }
120 return success;
121}
122
123static int split_count(const char *str)
124{
125 char *ctx;
126 int count = 0;
127 char buf[kPropertyValueMax];
128
129 strncpy(buf, str, sizeof(buf));
130 char *pBuf = buf;
131
132 while(strtok_r(pBuf, " ", &ctx) != NULL) {
133 count++;
134 pBuf = NULL;
135 }
136
137 return count;
138}
139
140static int split(char *buf, const char **argv)
141{
142 char *ctx;
143 int count = 0;
144 char *tok;
145 char *pBuf = buf;
146
147 while((tok = strtok_r(pBuf, " ", &ctx)) != NULL) {
148 argv[count++] = tok;
149 pBuf = NULL;
150 }
151
152 return count;
153}
154
155static void run_patchoat(int input_oat_fd, int input_vdex_fd, int out_oat_fd, int out_vdex_fd,
156 const char* input_oat_file_name, const char* input_vdex_file_name,
157 const char* output_oat_file_name, const char* output_vdex_file_name,
158 const char *pkgname ATTRIBUTE_UNUSED, const char *instruction_set)
159{
160 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig
161 static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
162
163 static const char* PATCHOAT_BIN = "/system/bin/patchoat";
164 if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
165 ALOGE("Instruction set %s longer than max length of %d",
166 instruction_set, MAX_INSTRUCTION_SET_LEN);
167 return;
168 }
169
170 /* input_file_name/input_fd should be the .odex/.oat file that is precompiled. I think*/
171 char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
172 char input_oat_fd_arg[strlen("--input-oat-fd=") + MAX_INT_LEN];
173 char input_vdex_fd_arg[strlen("--input-vdex-fd=") + MAX_INT_LEN];
174 char output_oat_fd_arg[strlen("--output-oat-fd=") + MAX_INT_LEN];
175 char output_vdex_fd_arg[strlen("--output-vdex-fd=") + MAX_INT_LEN];
176 const char* patched_image_location_arg = "--patched-image-location=/system/framework/boot.art";
177 // The caller has already gotten all the locks we need.
178 const char* no_lock_arg = "--no-lock-output";
179 sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
180 sprintf(output_oat_fd_arg, "--output-oat-fd=%d", out_oat_fd);
181 sprintf(input_oat_fd_arg, "--input-oat-fd=%d", input_oat_fd);
182 ALOGV("Running %s isa=%s in-oat-fd=%d (%s) in-vdex-fd=%d (%s) "
183 "out-oat-fd=%d (%s) out-vdex-fd=%d (%s)\n",
184 PATCHOAT_BIN, instruction_set,
185 input_oat_fd, input_oat_file_name,
186 input_vdex_fd, input_vdex_file_name,
187 out_oat_fd, output_oat_file_name,
188 out_vdex_fd, output_vdex_file_name);
189
190 /* patchoat, patched-image-location, no-lock, isa, input-fd, output-fd */
191 char* argv[9];
192 argv[0] = (char*) PATCHOAT_BIN;
193 argv[1] = (char*) patched_image_location_arg;
194 argv[2] = (char*) no_lock_arg;
195 argv[3] = instruction_set_arg;
196 argv[4] = input_oat_fd_arg;
197 argv[5] = input_vdex_fd_arg;
198 argv[6] = output_oat_fd_arg;
199 argv[7] = output_vdex_fd_arg;
200 argv[8] = NULL;
201
202 execv(PATCHOAT_BIN, (char* const *)argv);
203 ALOGE("execv(%s) failed: %s\n", PATCHOAT_BIN, strerror(errno));
204}
205
206static void run_dex2oat(int zip_fd, int oat_fd, int input_vdex_fd, int output_vdex_fd, int image_fd,
207 const char* input_file_name, const char* output_file_name, int swap_fd,
208 const char *instruction_set, const char* compiler_filter, bool vm_safe_mode,
209 bool debuggable, bool post_bootcomplete, int profile_fd, const char* shared_libraries) {
210 static const unsigned int MAX_INSTRUCTION_SET_LEN = 7;
211
212 if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
213 ALOGE("Instruction set %s longer than max length of %d",
214 instruction_set, MAX_INSTRUCTION_SET_LEN);
215 return;
216 }
217
218 char dex2oat_Xms_flag[kPropertyValueMax];
219 bool have_dex2oat_Xms_flag = get_property("dalvik.vm.dex2oat-Xms", dex2oat_Xms_flag, NULL) > 0;
220
221 char dex2oat_Xmx_flag[kPropertyValueMax];
222 bool have_dex2oat_Xmx_flag = get_property("dalvik.vm.dex2oat-Xmx", dex2oat_Xmx_flag, NULL) > 0;
223
224 char dex2oat_threads_buf[kPropertyValueMax];
225 bool have_dex2oat_threads_flag = get_property(post_bootcomplete
226 ? "dalvik.vm.dex2oat-threads"
227 : "dalvik.vm.boot-dex2oat-threads",
228 dex2oat_threads_buf,
229 NULL) > 0;
230 char dex2oat_threads_arg[kPropertyValueMax + 2];
231 if (have_dex2oat_threads_flag) {
232 sprintf(dex2oat_threads_arg, "-j%s", dex2oat_threads_buf);
233 }
234
235 char dex2oat_isa_features_key[kPropertyKeyMax];
236 sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", instruction_set);
237 char dex2oat_isa_features[kPropertyValueMax];
238 bool have_dex2oat_isa_features = get_property(dex2oat_isa_features_key,
239 dex2oat_isa_features, NULL) > 0;
240
241 char dex2oat_isa_variant_key[kPropertyKeyMax];
242 sprintf(dex2oat_isa_variant_key, "dalvik.vm.isa.%s.variant", instruction_set);
243 char dex2oat_isa_variant[kPropertyValueMax];
244 bool have_dex2oat_isa_variant = get_property(dex2oat_isa_variant_key,
245 dex2oat_isa_variant, NULL) > 0;
246
247 const char *dex2oat_norelocation = "-Xnorelocate";
248 bool have_dex2oat_relocation_skip_flag = false;
249
250 char dex2oat_flags[kPropertyValueMax];
251 int dex2oat_flags_count = get_property("dalvik.vm.dex2oat-flags",
252 dex2oat_flags, NULL) <= 0 ? 0 : split_count(dex2oat_flags);
253 ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags);
254
255 // If we booting without the real /data, don't spend time compiling.
256 char vold_decrypt[kPropertyValueMax];
257 bool have_vold_decrypt = get_property("vold.decrypt", vold_decrypt, "") > 0;
258 bool skip_compilation = (have_vold_decrypt &&
259 (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 ||
260 (strcmp(vold_decrypt, "1") == 0)));
261
262 bool generate_debug_info = property_get_bool("debug.generate-debug-info", false);
263
264 char app_image_format[kPropertyValueMax];
265 char image_format_arg[strlen("--image-format=") + kPropertyValueMax];
266 bool have_app_image_format =
267 image_fd >= 0 && get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
268 if (have_app_image_format) {
269 sprintf(image_format_arg, "--image-format=%s", app_image_format);
270 }
271
272 char dex2oat_large_app_threshold[kPropertyValueMax];
273 bool have_dex2oat_large_app_threshold =
274 get_property("dalvik.vm.dex2oat-very-large", dex2oat_large_app_threshold, NULL) > 0;
275 char dex2oat_large_app_threshold_arg[strlen("--very-large-app-threshold=") + kPropertyValueMax];
276 if (have_dex2oat_large_app_threshold) {
277 sprintf(dex2oat_large_app_threshold_arg,
278 "--very-large-app-threshold=%s",
279 dex2oat_large_app_threshold);
280 }
281
282 static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
283
284 static const char* RUNTIME_ARG = "--runtime-arg";
285
286 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig
287
288 char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
289 char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
290 char input_vdex_fd_arg[strlen("--input-vdex-fd=") + MAX_INT_LEN];
291 char output_vdex_fd_arg[strlen("--output-vdex-fd=") + MAX_INT_LEN];
292 char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
293 char oat_location_arg[strlen("--oat-location=") + PKG_PATH_MAX];
294 char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
295 char instruction_set_variant_arg[strlen("--instruction-set-variant=") + kPropertyValueMax];
296 char instruction_set_features_arg[strlen("--instruction-set-features=") + kPropertyValueMax];
297 char dex2oat_Xms_arg[strlen("-Xms") + kPropertyValueMax];
298 char dex2oat_Xmx_arg[strlen("-Xmx") + kPropertyValueMax];
299 char dex2oat_compiler_filter_arg[strlen("--compiler-filter=") + kPropertyValueMax];
300 bool have_dex2oat_swap_fd = false;
301 char dex2oat_swap_fd[strlen("--swap-fd=") + MAX_INT_LEN];
302 bool have_dex2oat_image_fd = false;
303 char dex2oat_image_fd[strlen("--app-image-fd=") + MAX_INT_LEN];
304
305 sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
306 sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
307 sprintf(input_vdex_fd_arg, "--input-vdex-fd=%d", input_vdex_fd);
308 sprintf(output_vdex_fd_arg, "--output-vdex-fd=%d", output_vdex_fd);
309 sprintf(oat_fd_arg, "--oat-fd=%d", oat_fd);
310 sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
311 sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
312 sprintf(instruction_set_variant_arg, "--instruction-set-variant=%s", dex2oat_isa_variant);
313 sprintf(instruction_set_features_arg, "--instruction-set-features=%s", dex2oat_isa_features);
314 if (swap_fd >= 0) {
315 have_dex2oat_swap_fd = true;
316 sprintf(dex2oat_swap_fd, "--swap-fd=%d", swap_fd);
317 }
318 if (image_fd >= 0) {
319 have_dex2oat_image_fd = true;
320 sprintf(dex2oat_image_fd, "--app-image-fd=%d", image_fd);
321 }
322
323 if (have_dex2oat_Xms_flag) {
324 sprintf(dex2oat_Xms_arg, "-Xms%s", dex2oat_Xms_flag);
325 }
326 if (have_dex2oat_Xmx_flag) {
327 sprintf(dex2oat_Xmx_arg, "-Xmx%s", dex2oat_Xmx_flag);
328 }
329
330 // Compute compiler filter.
331
332 bool have_dex2oat_compiler_filter_flag;
333 if (skip_compilation) {
334 strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=verify-none");
335 have_dex2oat_compiler_filter_flag = true;
336 have_dex2oat_relocation_skip_flag = true;
337 } else if (vm_safe_mode) {
338 strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=interpret-only");
339 have_dex2oat_compiler_filter_flag = true;
340 } else if (compiler_filter != nullptr &&
341 strlen(compiler_filter) + strlen("--compiler-filter=") <
342 arraysize(dex2oat_compiler_filter_arg)) {
343 sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", compiler_filter);
344 have_dex2oat_compiler_filter_flag = true;
345 } else {
346 char dex2oat_compiler_filter_flag[kPropertyValueMax];
347 have_dex2oat_compiler_filter_flag = get_property("dalvik.vm.dex2oat-filter",
348 dex2oat_compiler_filter_flag, NULL) > 0;
349 if (have_dex2oat_compiler_filter_flag) {
350 sprintf(dex2oat_compiler_filter_arg,
351 "--compiler-filter=%s",
352 dex2oat_compiler_filter_flag);
353 }
354 }
355
356 // Check whether all apps should be compiled debuggable.
357 if (!debuggable) {
358 char prop_buf[kPropertyValueMax];
359 debuggable =
360 (get_property("dalvik.vm.always_debuggable", prop_buf, "0") > 0) &&
361 (prop_buf[0] == '1');
362 }
363 char profile_arg[strlen("--profile-file-fd=") + MAX_INT_LEN];
364 if (profile_fd != -1) {
365 sprintf(profile_arg, "--profile-file-fd=%d", profile_fd);
366 }
367
368
369 ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
370
371 const char* argv[9 // program name, mandatory arguments and the final NULL
372 + (have_dex2oat_isa_variant ? 1 : 0)
373 + (have_dex2oat_isa_features ? 1 : 0)
374 + (have_dex2oat_Xms_flag ? 2 : 0)
375 + (have_dex2oat_Xmx_flag ? 2 : 0)
376 + (have_dex2oat_compiler_filter_flag ? 1 : 0)
377 + (have_dex2oat_threads_flag ? 1 : 0)
378 + (have_dex2oat_swap_fd ? 1 : 0)
379 + (have_dex2oat_image_fd ? 1 : 0)
380 + (have_dex2oat_relocation_skip_flag ? 2 : 0)
381 + (generate_debug_info ? 1 : 0)
382 + (debuggable ? 1 : 0)
383 + (have_app_image_format ? 1 : 0)
384 + dex2oat_flags_count
385 + (profile_fd == -1 ? 0 : 1)
386 + (shared_libraries != nullptr ? 4 : 0)
387 + (have_dex2oat_large_app_threshold ? 1 : 0)];
388 int i = 0;
389 argv[i++] = DEX2OAT_BIN;
390 argv[i++] = zip_fd_arg;
391 argv[i++] = zip_location_arg;
392 argv[i++] = input_vdex_fd_arg;
393 argv[i++] = output_vdex_fd_arg;
394 argv[i++] = oat_fd_arg;
395 argv[i++] = oat_location_arg;
396 argv[i++] = instruction_set_arg;
397 if (have_dex2oat_isa_variant) {
398 argv[i++] = instruction_set_variant_arg;
399 }
400 if (have_dex2oat_isa_features) {
401 argv[i++] = instruction_set_features_arg;
402 }
403 if (have_dex2oat_Xms_flag) {
404 argv[i++] = RUNTIME_ARG;
405 argv[i++] = dex2oat_Xms_arg;
406 }
407 if (have_dex2oat_Xmx_flag) {
408 argv[i++] = RUNTIME_ARG;
409 argv[i++] = dex2oat_Xmx_arg;
410 }
411 if (have_dex2oat_compiler_filter_flag) {
412 argv[i++] = dex2oat_compiler_filter_arg;
413 }
414 if (have_dex2oat_threads_flag) {
415 argv[i++] = dex2oat_threads_arg;
416 }
417 if (have_dex2oat_swap_fd) {
418 argv[i++] = dex2oat_swap_fd;
419 }
420 if (have_dex2oat_image_fd) {
421 argv[i++] = dex2oat_image_fd;
422 }
423 if (generate_debug_info) {
424 argv[i++] = "--generate-debug-info";
425 }
426 if (debuggable) {
427 argv[i++] = "--debuggable";
428 }
429 if (have_app_image_format) {
430 argv[i++] = image_format_arg;
431 }
432 if (have_dex2oat_large_app_threshold) {
433 argv[i++] = dex2oat_large_app_threshold_arg;
434 }
435 if (dex2oat_flags_count) {
436 i += split(dex2oat_flags, argv + i);
437 }
438 if (have_dex2oat_relocation_skip_flag) {
439 argv[i++] = RUNTIME_ARG;
440 argv[i++] = dex2oat_norelocation;
441 }
442 if (profile_fd != -1) {
443 argv[i++] = profile_arg;
444 }
445 if (shared_libraries != nullptr) {
446 argv[i++] = RUNTIME_ARG;
447 argv[i++] = "-classpath";
448 argv[i++] = RUNTIME_ARG;
449 argv[i++] = shared_libraries;
450 }
451 // Do not add after dex2oat_flags, they should override others for debugging.
452 argv[i] = NULL;
453
454 execv(DEX2OAT_BIN, (char * const *)argv);
455 ALOGE("execv(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
456}
457
458/*
459 * Whether dexopt should use a swap file when compiling an APK.
460 *
461 * If kAlwaysProvideSwapFile, do this on all devices (dex2oat will make a more informed decision
462 * itself, anyways).
463 *
464 * Otherwise, read "dalvik.vm.dex2oat-swap". If the property exists, return whether it is "true".
465 *
466 * Otherwise, return true if this is a low-mem device.
467 *
468 * Otherwise, return default value.
469 */
470static bool kAlwaysProvideSwapFile = false;
471static bool kDefaultProvideSwapFile = true;
472
473static bool ShouldUseSwapFileForDexopt() {
474 if (kAlwaysProvideSwapFile) {
475 return true;
476 }
477
478 // Check the "override" property. If it exists, return value == "true".
479 char dex2oat_prop_buf[kPropertyValueMax];
480 if (get_property("dalvik.vm.dex2oat-swap", dex2oat_prop_buf, "") > 0) {
481 if (strcmp(dex2oat_prop_buf, "true") == 0) {
482 return true;
483 } else {
484 return false;
485 }
486 }
487
488 // Shortcut for default value. This is an implementation optimization for the process sketched
489 // above. If the default value is true, we can avoid to check whether this is a low-mem device,
490 // as low-mem is never returning false. The compiler will optimize this away if it can.
491 if (kDefaultProvideSwapFile) {
492 return true;
493 }
494
495 bool is_low_mem = property_get_bool("ro.config.low_ram", false);
496 if (is_low_mem) {
497 return true;
498 }
499
500 // Default value must be false here.
501 return kDefaultProvideSwapFile;
502}
503
504static void SetDex2OatAndPatchOatScheduling(bool set_to_bg) {
505 if (set_to_bg) {
506 if (set_sched_policy(0, SP_BACKGROUND) < 0) {
507 ALOGE("set_sched_policy failed: %s\n", strerror(errno));
508 exit(70);
509 }
510 if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
511 ALOGE("setpriority failed: %s\n", strerror(errno));
512 exit(71);
513 }
514 }
515}
516
517static void close_all_fds(const std::vector<fd_t>& fds, const char* description) {
518 for (size_t i = 0; i < fds.size(); i++) {
519 if (close(fds[i]) != 0) {
520 PLOG(WARNING) << "Failed to close fd for " << description << " at index " << i;
521 }
522 }
523}
524
525static fd_t open_profile_dir(const std::string& profile_dir) {
526 fd_t profile_dir_fd = TEMP_FAILURE_RETRY(open(profile_dir.c_str(),
527 O_PATH | O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW));
528 if (profile_dir_fd < 0) {
529 // In a multi-user environment, these directories can be created at
530 // different points and it's possible we'll attempt to open a profile
531 // dir before it exists.
532 if (errno != ENOENT) {
533 PLOG(ERROR) << "Failed to open profile_dir: " << profile_dir;
534 }
535 }
536 return profile_dir_fd;
537}
538
539static fd_t open_primary_profile_file_from_dir(const std::string& profile_dir, mode_t open_mode) {
540 fd_t profile_dir_fd = open_profile_dir(profile_dir);
541 if (profile_dir_fd < 0) {
542 return -1;
543 }
544
545 fd_t profile_fd = -1;
546 std::string profile_file = create_primary_profile(profile_dir);
547
548 profile_fd = TEMP_FAILURE_RETRY(open(profile_file.c_str(), open_mode | O_NOFOLLOW));
549 if (profile_fd == -1) {
550 // It's not an error if the profile file does not exist.
551 if (errno != ENOENT) {
552 PLOG(ERROR) << "Failed to lstat profile_dir: " << profile_dir;
553 }
554 }
555 // TODO(calin): use AutoCloseFD instead of closing the fd manually.
556 if (close(profile_dir_fd) != 0) {
557 PLOG(WARNING) << "Could not close profile dir " << profile_dir;
558 }
559 return profile_fd;
560}
561
562static fd_t open_primary_profile_file(userid_t user, const char* pkgname) {
563 std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
564 return open_primary_profile_file_from_dir(profile_dir, O_RDONLY);
565}
566
567static fd_t open_reference_profile(uid_t uid, const char* pkgname, bool read_write) {
568 std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
569 int flags = read_write ? O_RDWR | O_CREAT : O_RDONLY;
570 fd_t fd = open_primary_profile_file_from_dir(reference_profile_dir, flags);
571 if (fd < 0) {
572 return -1;
573 }
574 if (read_write) {
575 // Fix the owner.
576 if (fchown(fd, uid, uid) < 0) {
577 close(fd);
578 return -1;
579 }
580 }
581 return fd;
582}
583
584static void open_profile_files(uid_t uid, const char* pkgname,
585 /*out*/ std::vector<fd_t>* profiles_fd, /*out*/ fd_t* reference_profile_fd) {
586 // Open the reference profile in read-write mode as profman might need to save the merge.
587 *reference_profile_fd = open_reference_profile(uid, pkgname, /*read_write*/ true);
588 if (*reference_profile_fd < 0) {
589 // We can't access the reference profile file.
590 return;
591 }
592
593 std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
594 for (auto user : users) {
595 fd_t profile_fd = open_primary_profile_file(user, pkgname);
596 // Add to the lists only if both fds are valid.
597 if (profile_fd >= 0) {
598 profiles_fd->push_back(profile_fd);
599 }
600 }
601}
602
603static void drop_capabilities(uid_t uid) {
604 if (setgid(uid) != 0) {
605 ALOGE("setgid(%d) failed in installd during dexopt\n", uid);
606 exit(64);
607 }
608 if (setuid(uid) != 0) {
609 ALOGE("setuid(%d) failed in installd during dexopt\n", uid);
610 exit(65);
611 }
612 // drop capabilities
613 struct __user_cap_header_struct capheader;
614 struct __user_cap_data_struct capdata[2];
615 memset(&capheader, 0, sizeof(capheader));
616 memset(&capdata, 0, sizeof(capdata));
617 capheader.version = _LINUX_CAPABILITY_VERSION_3;
618 if (capset(&capheader, &capdata[0]) < 0) {
619 ALOGE("capset failed: %s\n", strerror(errno));
620 exit(66);
621 }
622}
623
624static constexpr int PROFMAN_BIN_RETURN_CODE_COMPILE = 0;
625static constexpr int PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION = 1;
626static constexpr int PROFMAN_BIN_RETURN_CODE_BAD_PROFILES = 2;
627static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_IO = 3;
628static constexpr int PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING = 4;
629
630static void run_profman_merge(const std::vector<fd_t>& profiles_fd, fd_t reference_profile_fd) {
631 static const size_t MAX_INT_LEN = 32;
632 static const char* PROFMAN_BIN = "/system/bin/profman";
633
634 std::vector<std::string> profile_args(profiles_fd.size());
635 char profile_buf[strlen("--profile-file-fd=") + MAX_INT_LEN];
636 for (size_t k = 0; k < profiles_fd.size(); k++) {
637 sprintf(profile_buf, "--profile-file-fd=%d", profiles_fd[k]);
638 profile_args[k].assign(profile_buf);
639 }
640 char reference_profile_arg[strlen("--reference-profile-file-fd=") + MAX_INT_LEN];
641 sprintf(reference_profile_arg, "--reference-profile-file-fd=%d", reference_profile_fd);
642
643 // program name, reference profile fd, the final NULL and the profile fds
644 const char* argv[3 + profiles_fd.size()];
645 int i = 0;
646 argv[i++] = PROFMAN_BIN;
647 argv[i++] = reference_profile_arg;
648 for (size_t k = 0; k < profile_args.size(); k++) {
649 argv[i++] = profile_args[k].c_str();
650 }
651 // Do not add after dex2oat_flags, they should override others for debugging.
652 argv[i] = NULL;
653
654 execv(PROFMAN_BIN, (char * const *)argv);
655 ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno));
656 exit(68); /* only get here on exec failure */
657}
658
659// Decides if profile guided compilation is needed or not based on existing profiles.
660// Returns true if there is enough information in the current profiles that worth
661// a re-compilation of the package.
662// If the return value is true all the current profiles would have been merged into
663// the reference profiles accessible with open_reference_profile().
664bool analyse_profiles(uid_t uid, const char* pkgname) {
665 std::vector<fd_t> profiles_fd;
666 fd_t reference_profile_fd = -1;
667 open_profile_files(uid, pkgname, &profiles_fd, &reference_profile_fd);
668 if (profiles_fd.empty() || (reference_profile_fd == -1)) {
669 // Skip profile guided compilation because no profiles were found.
670 // Or if the reference profile info couldn't be opened.
671 close_all_fds(profiles_fd, "profiles_fd");
672 if ((reference_profile_fd != - 1) && (close(reference_profile_fd) != 0)) {
673 PLOG(WARNING) << "Failed to close fd for reference profile";
674 }
675 return false;
676 }
677
678 ALOGV("PROFMAN (MERGE): --- BEGIN '%s' ---\n", pkgname);
679
680 pid_t pid = fork();
681 if (pid == 0) {
682 /* child -- drop privileges before continuing */
683 drop_capabilities(uid);
684 run_profman_merge(profiles_fd, reference_profile_fd);
685 exit(68); /* only get here on exec failure */
686 }
687 /* parent */
688 int return_code = wait_child(pid);
689 bool need_to_compile = false;
690 bool should_clear_current_profiles = false;
691 bool should_clear_reference_profile = false;
692 if (!WIFEXITED(return_code)) {
693 LOG(WARNING) << "profman failed for package " << pkgname << ": " << return_code;
694 } else {
695 return_code = WEXITSTATUS(return_code);
696 switch (return_code) {
697 case PROFMAN_BIN_RETURN_CODE_COMPILE:
698 need_to_compile = true;
699 should_clear_current_profiles = true;
700 should_clear_reference_profile = false;
701 break;
702 case PROFMAN_BIN_RETURN_CODE_SKIP_COMPILATION:
703 need_to_compile = false;
704 should_clear_current_profiles = false;
705 should_clear_reference_profile = false;
706 break;
707 case PROFMAN_BIN_RETURN_CODE_BAD_PROFILES:
708 LOG(WARNING) << "Bad profiles for package " << pkgname;
709 need_to_compile = false;
710 should_clear_current_profiles = true;
711 should_clear_reference_profile = true;
712 break;
713 case PROFMAN_BIN_RETURN_CODE_ERROR_IO: // fall-through
714 case PROFMAN_BIN_RETURN_CODE_ERROR_LOCKING:
715 // Temporary IO problem (e.g. locking). Ignore but log a warning.
716 LOG(WARNING) << "IO error while reading profiles for package " << pkgname;
717 need_to_compile = false;
718 should_clear_current_profiles = false;
719 should_clear_reference_profile = false;
720 break;
721 default:
722 // Unknown return code or error. Unlink profiles.
723 LOG(WARNING) << "Unknown error code while processing profiles for package " << pkgname
724 << ": " << return_code;
725 need_to_compile = false;
726 should_clear_current_profiles = true;
727 should_clear_reference_profile = true;
728 break;
729 }
730 }
731 close_all_fds(profiles_fd, "profiles_fd");
732 if (close(reference_profile_fd) != 0) {
733 PLOG(WARNING) << "Failed to close fd for reference profile";
734 }
735 if (should_clear_current_profiles) {
736 clear_current_profiles(pkgname);
737 }
738 if (should_clear_reference_profile) {
739 clear_reference_profile(pkgname);
740 }
741 return need_to_compile;
742}
743
744static void run_profman_dump(const std::vector<fd_t>& profile_fds,
745 fd_t reference_profile_fd,
746 const std::vector<std::string>& dex_locations,
747 const std::vector<fd_t>& apk_fds,
748 fd_t output_fd) {
749 std::vector<std::string> profman_args;
750 static const char* PROFMAN_BIN = "/system/bin/profman";
751 profman_args.push_back(PROFMAN_BIN);
752 profman_args.push_back("--dump-only");
753 profman_args.push_back(StringPrintf("--dump-output-to-fd=%d", output_fd));
754 if (reference_profile_fd != -1) {
755 profman_args.push_back(StringPrintf("--reference-profile-file-fd=%d",
756 reference_profile_fd));
757 }
758 for (fd_t profile_fd : profile_fds) {
759 profman_args.push_back(StringPrintf("--profile-file-fd=%d", profile_fd));
760 }
761 for (const std::string& dex_location : dex_locations) {
762 profman_args.push_back(StringPrintf("--dex-location=%s", dex_location.c_str()));
763 }
764 for (fd_t apk_fd : apk_fds) {
765 profman_args.push_back(StringPrintf("--apk-fd=%d", apk_fd));
766 }
767 const char **argv = new const char*[profman_args.size() + 1];
768 size_t i = 0;
769 for (const std::string& profman_arg : profman_args) {
770 argv[i++] = profman_arg.c_str();
771 }
772 argv[i] = NULL;
773
774 execv(PROFMAN_BIN, (char * const *)argv);
775 ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno));
776 exit(68); /* only get here on exec failure */
777}
778
779static const char* get_location_from_path(const char* path) {
780 static constexpr char kLocationSeparator = '/';
781 const char *location = strrchr(path, kLocationSeparator);
782 if (location == NULL) {
783 return path;
784 } else {
785 // Skip the separator character.
786 return location + 1;
787 }
788}
789
790bool dump_profiles(int32_t uid, const char* pkgname, const char* code_paths) {
791 std::vector<fd_t> profile_fds;
792 fd_t reference_profile_fd = -1;
793 std::string out_file_name = StringPrintf("/data/misc/profman/%s.txt", pkgname);
794
795 ALOGV("PROFMAN (DUMP): --- BEGIN '%s' ---\n", pkgname);
796
797 open_profile_files(uid, pkgname, &profile_fds, &reference_profile_fd);
798
799 const bool has_reference_profile = (reference_profile_fd != -1);
800 const bool has_profiles = !profile_fds.empty();
801
802 if (!has_reference_profile && !has_profiles) {
803 ALOGE("profman dump: no profiles to dump for '%s'", pkgname);
804 return false;
805 }
806
807 fd_t output_fd = open(out_file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW);
808 if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
809 ALOGE("installd cannot chmod '%s' dump_profile\n", out_file_name.c_str());
810 return false;
811 }
812 std::vector<std::string> code_full_paths = base::Split(code_paths, ";");
813 std::vector<std::string> dex_locations;
814 std::vector<fd_t> apk_fds;
815 for (const std::string& code_full_path : code_full_paths) {
816 const char* full_path = code_full_path.c_str();
817 fd_t apk_fd = open(full_path, O_RDONLY | O_NOFOLLOW);
818 if (apk_fd == -1) {
819 ALOGE("installd cannot open '%s'\n", full_path);
820 return false;
821 }
822 dex_locations.push_back(get_location_from_path(full_path));
823 apk_fds.push_back(apk_fd);
824 }
825
826 pid_t pid = fork();
827 if (pid == 0) {
828 /* child -- drop privileges before continuing */
829 drop_capabilities(uid);
830 run_profman_dump(profile_fds, reference_profile_fd, dex_locations,
831 apk_fds, output_fd);
832 exit(68); /* only get here on exec failure */
833 }
834 /* parent */
835 close_all_fds(apk_fds, "apk_fds");
836 close_all_fds(profile_fds, "profile_fds");
837 if (close(reference_profile_fd) != 0) {
838 PLOG(WARNING) << "Failed to close fd for reference profile";
839 }
840 int return_code = wait_child(pid);
841 if (!WIFEXITED(return_code)) {
842 LOG(WARNING) << "profman failed for package " << pkgname << ": "
843 << return_code;
844 return false;
845 }
846 return true;
847}
848
849static std::string replace_file_extension(const std::string& oat_path, const std::string& new_ext) {
850 // A standard dalvik-cache entry. Replace ".dex" with `new_ext`.
851 if (EndsWith(oat_path, ".dex")) {
852 std::string new_path = oat_path;
853 new_path.replace(new_path.length() - strlen(".dex"), strlen(".dex"), new_ext);
854 CHECK(EndsWith(new_path, new_ext.c_str()));
855 return new_path;
856 }
857
858 // An odex entry. Not that this may not be an extension, e.g., in the OTA
859 // case (where the base name will have an extension for the B artifact).
860 size_t odex_pos = oat_path.rfind(".odex");
861 if (odex_pos != std::string::npos) {
862 std::string new_path = oat_path;
863 new_path.replace(odex_pos, strlen(".odex"), new_ext);
864 CHECK_NE(new_path.find(new_ext), std::string::npos);
865 return new_path;
866 }
867
868 // Don't know how to handle this.
869 return "";
870}
871
872// Translate the given oat path to an art (app image) path. An empty string
873// denotes an error.
874static std::string create_image_filename(const std::string& oat_path) {
875 return replace_file_extension(oat_path, ".art");
876}
877
878// Translate the given oat path to a vdex path. An empty string denotes an error.
879static std::string create_vdex_filename(const std::string& oat_path) {
880 return replace_file_extension(oat_path, ".vdex");
881}
882
883static bool add_extension_to_file_name(char* file_name, const char* extension) {
884 if (strlen(file_name) + strlen(extension) + 1 > PKG_PATH_MAX) {
885 return false;
886 }
887 strcat(file_name, extension);
888 return true;
889}
890
891static int open_output_file(const char* file_name, bool recreate, int permissions) {
892 int flags = O_RDWR | O_CREAT;
893 if (recreate) {
894 if (unlink(file_name) < 0) {
895 if (errno != ENOENT) {
896 PLOG(ERROR) << "open_output_file: Couldn't unlink " << file_name;
897 }
898 }
899 flags |= O_EXCL;
900 }
901 return open(file_name, flags, permissions);
902}
903
904static bool set_permissions_and_ownership(int fd, bool is_public, int uid, const char* path) {
905 if (fchmod(fd,
906 S_IRUSR|S_IWUSR|S_IRGRP |
907 (is_public ? S_IROTH : 0)) < 0) {
908 ALOGE("installd cannot chmod '%s' during dexopt\n", path);
909 return false;
910 } else if (fchown(fd, AID_SYSTEM, uid) < 0) {
911 ALOGE("installd cannot chown '%s' during dexopt\n", path);
912 return false;
913 }
914 return true;
915}
916
917static bool IsOutputDalvikCache(const char* oat_dir) {
918 // InstallerConnection.java (which invokes installd) transforms Java null arguments
919 // into '!'. Play it safe by handling it both.
920 // TODO: ensure we never get null.
921 // TODO: pass a flag instead of inferring if the output is dalvik cache.
922 return oat_dir == nullptr || oat_dir[0] == '!';
923}
924
925static bool create_oat_out_path(const char* apk_path, const char* instruction_set,
926 const char* oat_dir, /*out*/ char* out_oat_path) {
927 // Early best-effort check whether we can fit the the path into our buffers.
928 // Note: the cache path will require an additional 5 bytes for ".swap", but we'll try to run
929 // without a swap file, if necessary. Reference profiles file also add an extra ".prof"
930 // extension to the cache path (5 bytes).
931 if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
932 ALOGE("apk_path too long '%s'\n", apk_path);
933 return false;
934 }
935
936 if (!IsOutputDalvikCache(oat_dir)) {
937 if (validate_apk_path(oat_dir)) {
938 ALOGE("cannot validate apk path with oat_dir '%s'\n", oat_dir);
939 return false;
940 }
941 if (!calculate_oat_file_path(out_oat_path, oat_dir, apk_path, instruction_set)) {
942 return false;
943 }
944 } else {
945 if (!create_cache_path(out_oat_path, apk_path, instruction_set)) {
946 return false;
947 }
948 }
949 return true;
950}
951
952// Helper for fd management. This is similar to a unique_fd in that it closes the file descriptor
953// on destruction. It will also run the given cleanup (unless told not to) after closing.
954//
955// Usage example:
956//
957// Dex2oatFileWrapper<std::function<void ()>> file(open(...),
958// [name]() {
959// unlink(name.c_str());
960// });
961// // Note: care needs to be taken about name, as it needs to have a lifetime longer than the
962// wrapper if captured as a reference.
963//
964// if (file.get() == -1) {
965// // Error opening...
966// }
967//
968// ...
969// if (error) {
970// // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will run
971// // and delete the file (after the fd is closed).
972// return -1;
973// }
974//
975// (Success case)
976// file.SetCleanup(false);
977// // At this point, when the Dex2oatFileWrapper is destructed, the cleanup function will not run
978// // (leaving the file around; after the fd is closed).
979//
980template <typename Cleanup>
981class Dex2oatFileWrapper {
982 public:
983 Dex2oatFileWrapper() : value_(-1), cleanup_(), do_cleanup_(true) {
984 }
985
986 Dex2oatFileWrapper(int value, Cleanup cleanup)
987 : value_(value), cleanup_(cleanup), do_cleanup_(true) {}
988
989 ~Dex2oatFileWrapper() {
990 reset(-1);
991 }
992
993 int get() {
994 return value_;
995 }
996
997 void SetCleanup(bool cleanup) {
998 do_cleanup_ = cleanup;
999 }
1000
1001 void reset(int new_value) {
1002 if (value_ >= 0) {
1003 close(value_);
1004 }
1005 if (do_cleanup_ && cleanup_ != nullptr) {
1006 cleanup_();
1007 }
1008
1009 value_ = new_value;
1010 }
1011
1012 void reset(int new_value, Cleanup new_cleanup) {
1013 if (value_ >= 0) {
1014 close(value_);
1015 }
1016 if (do_cleanup_ && cleanup_ != nullptr) {
1017 cleanup_();
1018 }
1019
1020 value_ = new_value;
1021 cleanup_ = new_cleanup;
1022 }
1023
1024 private:
1025 int value_;
1026 Cleanup cleanup_;
1027 bool do_cleanup_;
1028};
1029
1030int dexopt(const char* apk_path, uid_t uid, const char* pkgname, const char* instruction_set,
1031 int dexopt_needed, const char* oat_dir, int dexopt_flags,const char* compiler_filter,
1032 const char* volume_uuid ATTRIBUTE_UNUSED, const char* shared_libraries) {
1033 bool is_public = ((dexopt_flags & DEXOPT_PUBLIC) != 0);
1034 bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0;
1035 bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
1036 bool boot_complete = (dexopt_flags & DEXOPT_BOOTCOMPLETE) != 0;
1037 bool profile_guided = (dexopt_flags & DEXOPT_PROFILE_GUIDED) != 0;
1038
1039 CHECK(pkgname != nullptr);
1040 CHECK(pkgname[0] != 0);
1041
1042 // Public apps should not be compiled with profile information ever. Same goes for the special
1043 // package '*' used for the system server.
1044 Dex2oatFileWrapper<std::function<void ()>> reference_profile_fd;
1045 if (!is_public && pkgname[0] != '*') {
1046 // Open reference profile in read only mode as dex2oat does not get write permissions.
1047 const std::string pkgname_str(pkgname);
1048 reference_profile_fd.reset(open_reference_profile(uid, pkgname, /*read_write*/ false),
1049 [pkgname_str]() {
1050 clear_reference_profile(pkgname_str.c_str());
1051 });
1052 // Note: it's OK to not find a profile here.
1053 }
1054
1055 if ((dexopt_flags & ~DEXOPT_MASK) != 0) {
1056 LOG_FATAL("dexopt flags contains unknown fields\n");
1057 }
1058
1059 char out_oat_path[PKG_PATH_MAX];
1060 if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_oat_path)) {
1061 return false;
1062 }
1063
1064 const char *input_file;
1065 char in_odex_path[PKG_PATH_MAX];
1066 int dexopt_action = abs(dexopt_needed);
1067 bool is_odex_location = dexopt_needed < 0;
1068 switch (dexopt_action) {
1069 case DEX2OAT_FROM_SCRATCH:
1070 case DEX2OAT_FOR_BOOT_IMAGE:
1071 case DEX2OAT_FOR_FILTER:
1072 case DEX2OAT_FOR_RELOCATION:
1073 input_file = apk_path;
1074 break;
1075
1076 case PATCHOAT_FOR_RELOCATION:
1077 if (is_odex_location) {
1078 if (!calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
1079 return -1;
1080 }
1081 input_file = in_odex_path;
1082 } else {
1083 input_file = out_oat_path;
1084 }
1085 break;
1086
1087 default:
1088 ALOGE("Invalid dexopt needed: %d\n", dexopt_needed);
1089 return 72;
1090 }
1091
1092 struct stat input_stat;
1093 memset(&input_stat, 0, sizeof(input_stat));
1094 stat(input_file, &input_stat);
1095
1096 // Open the input file. If running dex2oat, `input_file` is the APK. If running
1097 // patchoat, it is the OAT file to be relocated.
1098 base::unique_fd input_fd(open(input_file, O_RDONLY, 0));
1099 if (input_fd.get() < 0) {
1100 ALOGE("installd cannot open '%s' for input during dexopt\n", input_file);
1101 return -1;
1102 }
1103
1104 // Create the output OAT file.
1105 const std::string out_oat_path_str(out_oat_path);
1106 Dex2oatFileWrapper<std::function<void ()>> out_oat_fd(
1107 open_output_file(out_oat_path, /*recreate*/true, /*permissions*/0644),
1108 [out_oat_path_str]() { unlink(out_oat_path_str.c_str()); });
1109 if (out_oat_fd.get() < 0) {
1110 ALOGE("installd cannot open '%s' for output during dexopt\n", out_oat_path);
1111 return -1;
1112 }
1113 if (!set_permissions_and_ownership(out_oat_fd.get(), is_public, uid, out_oat_path)) {
1114 return -1;
1115 }
1116
1117 // Open the existing VDEX. We do this before creating the new output VDEX, which will
1118 // unlink the old one.
1119 base::unique_fd in_vdex_fd;
1120 std::string in_vdex_path_str;
1121 if (dexopt_action == PATCHOAT_FOR_RELOCATION) {
1122 // `input_file` is the OAT file to be relocated. The VDEX has to be there as well.
1123 in_vdex_path_str = create_vdex_filename(input_file);
1124 if (in_vdex_path_str.empty()) {
1125 ALOGE("installd cannot compute input vdex location for '%s'\n", input_file);
1126 return -1;
1127 }
1128 in_vdex_fd.reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
1129 if (in_vdex_fd.get() < 0) {
1130 ALOGE("installd cannot open '%s' for input during dexopt: %s\n",
1131 in_vdex_path_str.c_str(), strerror(errno));
1132 return -1;
1133 }
1134 } else if (dexopt_action != DEX2OAT_FROM_SCRATCH) {
1135 // Open the possibly existing vdex. If none exist, we pass -1 to dex2oat for input-vdex-fd.
1136 const char* path = nullptr;
1137 if (is_odex_location) {
1138 if (calculate_odex_file_path(in_odex_path, apk_path, instruction_set)) {
1139 path = in_odex_path;
1140 } else {
1141 ALOGE("installd cannot compute input vdex location for '%s'\n", apk_path);
1142 return -1;
1143 }
1144 } else {
1145 path = out_oat_path;
1146 }
1147 in_vdex_path_str = create_vdex_filename(path);
1148 if (in_vdex_path_str.empty()) {
1149 ALOGE("installd cannot compute input vdex location for '%s'\n", path);
1150 return -1;
1151 }
1152 in_vdex_fd.reset(open(in_vdex_path_str.c_str(), O_RDONLY, 0));
1153 }
1154
1155 // Infer the name of the output VDEX and create it.
1156 const std::string out_vdex_path_str = create_vdex_filename(out_oat_path_str);
1157 if (out_vdex_path_str.empty()) {
1158 return -1;
1159 }
1160 Dex2oatFileWrapper<std::function<void ()>> out_vdex_fd(
1161 open_output_file(out_vdex_path_str.c_str(), /*recreate*/true, /*permissions*/0644),
1162 [out_vdex_path_str]() { unlink(out_vdex_path_str.c_str()); });
1163 if (out_vdex_fd.get() < 0) {
1164 ALOGE("installd cannot open '%s' for output during dexopt\n", out_vdex_path_str.c_str());
1165 return -1;
1166 }
1167 if (!set_permissions_and_ownership(out_vdex_fd.get(), is_public,
1168 uid, out_vdex_path_str.c_str())) {
1169 return -1;
1170 }
1171
1172 // Create a swap file if necessary.
1173 base::unique_fd swap_fd;
1174 if (ShouldUseSwapFileForDexopt()) {
1175 // Make sure there really is enough space.
1176 char swap_file_name[PKG_PATH_MAX];
1177 strcpy(swap_file_name, out_oat_path);
1178 if (add_extension_to_file_name(swap_file_name, ".swap")) {
1179 swap_fd.reset(open_output_file(swap_file_name, /*recreate*/true, /*permissions*/0600));
1180 }
1181 if (swap_fd.get() < 0) {
1182 // Could not create swap file. Optimistically go on and hope that we can compile
1183 // without it.
1184 ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
1185 } else {
1186 // Immediately unlink. We don't really want to hit flash.
1187 if (unlink(swap_file_name) < 0) {
1188 PLOG(ERROR) << "Couldn't unlink swap file " << swap_file_name;
1189 }
1190 }
1191 }
1192
1193 // Avoid generating an app image for extract only since it will not contain any classes.
1194 Dex2oatFileWrapper<std::function<void ()>> image_fd;
1195 const std::string image_path = create_image_filename(out_oat_path);
1196 if (dexopt_action != PATCHOAT_FOR_RELOCATION && !image_path.empty()) {
1197 char app_image_format[kPropertyValueMax];
1198 bool have_app_image_format =
1199 get_property("dalvik.vm.appimageformat", app_image_format, NULL) > 0;
1200 // Use app images only if it is enabled (by a set image format) and we are compiling
1201 // profile-guided (so the app image doesn't conservatively contain all classes).
1202 if (profile_guided && have_app_image_format) {
1203 // Recreate is true since we do not want to modify a mapped image. If the app is
1204 // already running and we modify the image file, it can cause crashes (b/27493510).
1205 image_fd.reset(open_output_file(image_path.c_str(),
1206 true /*recreate*/,
1207 0600 /*permissions*/),
1208 [image_path]() { unlink(image_path.c_str()); }
1209 );
1210 if (image_fd.get() < 0) {
1211 // Could not create application image file. Go on since we can compile without
1212 // it.
1213 LOG(ERROR) << "installd could not create '"
1214 << image_path
1215 << "' for image file during dexopt";
1216 } else if (!set_permissions_and_ownership(image_fd.get(),
1217 is_public,
1218 uid,
1219 image_path.c_str())) {
1220 image_fd.reset(-1);
1221 }
1222 }
1223 // If we have a valid image file path but no image fd, explicitly erase the image file.
1224 if (image_fd.get() < 0) {
1225 if (unlink(image_path.c_str()) < 0) {
1226 if (errno != ENOENT) {
1227 PLOG(ERROR) << "Couldn't unlink image file " << image_path;
1228 }
1229 }
1230 }
1231 }
1232
1233 ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file);
1234
1235 pid_t pid = fork();
1236 if (pid == 0) {
1237 /* child -- drop privileges before continuing */
1238 drop_capabilities(uid);
1239
1240 SetDex2OatAndPatchOatScheduling(boot_complete);
1241 if (flock(out_oat_fd.get(), LOCK_EX | LOCK_NB) != 0) {
1242 ALOGE("flock(%s) failed: %s\n", out_oat_path, strerror(errno));
1243 _exit(67);
1244 }
1245
1246 if (dexopt_action == PATCHOAT_FOR_RELOCATION) {
1247 run_patchoat(input_fd.get(),
1248 in_vdex_fd.get(),
1249 out_oat_fd.get(),
1250 out_vdex_fd.get(),
1251 input_file,
1252 in_vdex_path_str.c_str(),
1253 out_oat_path,
1254 out_vdex_path_str.c_str(),
1255 pkgname,
1256 instruction_set);
1257 } else {
1258 // Pass dex2oat the relative path to the input file.
1259 const char *input_file_name = get_location_from_path(input_file);
1260 run_dex2oat(input_fd.get(),
1261 out_oat_fd.get(),
1262 in_vdex_fd.get(),
1263 out_vdex_fd.get(),
1264 image_fd.get(),
1265 input_file_name,
1266 out_oat_path,
1267 swap_fd.get(),
1268 instruction_set,
1269 compiler_filter,
1270 vm_safe_mode,
1271 debuggable,
1272 boot_complete,
1273 reference_profile_fd.get(),
1274 shared_libraries);
1275 }
1276 _exit(68); /* only get here on exec failure */
1277 } else {
1278 int res = wait_child(pid);
1279 if (res == 0) {
1280 ALOGV("DexInv: --- END '%s' (success) ---\n", input_file);
1281 } else {
1282 ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", input_file, res);
1283 return -1;
1284 }
1285 }
1286
1287 struct utimbuf ut;
1288 ut.actime = input_stat.st_atime;
1289 ut.modtime = input_stat.st_mtime;
1290 utime(out_oat_path, &ut);
1291
1292 // We've been successful, don't delete output.
1293 out_oat_fd.SetCleanup(false);
1294 out_vdex_fd.SetCleanup(false);
1295 image_fd.SetCleanup(false);
1296 reference_profile_fd.SetCleanup(false);
1297
1298 return 0;
1299}
1300
1301// Helper for move_ab, so that we can have common failure-case cleanup.
1302static bool unlink_and_rename(const char* from, const char* to) {
1303 // Check whether "from" exists, and if so whether it's regular. If it is, unlink. Otherwise,
1304 // return a failure.
1305 struct stat s;
1306 if (stat(to, &s) == 0) {
1307 if (!S_ISREG(s.st_mode)) {
1308 LOG(ERROR) << from << " is not a regular file to replace for A/B.";
1309 return false;
1310 }
1311 if (unlink(to) != 0) {
1312 LOG(ERROR) << "Could not unlink " << to << " to move A/B.";
1313 return false;
1314 }
1315 } else {
1316 // This may be a permission problem. We could investigate the error code, but we'll just
1317 // let the rename failure do the work for us.
1318 }
1319
1320 // Try to rename "to" to "from."
1321 if (rename(from, to) != 0) {
1322 PLOG(ERROR) << "Could not rename " << from << " to " << to;
1323 return false;
1324 }
1325 return true;
1326}
1327
1328// Move/rename a B artifact (from) to an A artifact (to).
1329static bool move_ab_path(const std::string& b_path, const std::string& a_path) {
1330 // Check whether B exists.
1331 {
1332 struct stat s;
1333 if (stat(b_path.c_str(), &s) != 0) {
1334 // Silently ignore for now. The service calling this isn't smart enough to understand
1335 // lack of artifacts at the moment.
1336 return false;
1337 }
1338 if (!S_ISREG(s.st_mode)) {
1339 LOG(ERROR) << "A/B artifact " << b_path << " is not a regular file.";
1340 // Try to unlink, but swallow errors.
1341 unlink(b_path.c_str());
1342 return false;
1343 }
1344 }
1345
1346 // Rename B to A.
1347 if (!unlink_and_rename(b_path.c_str(), a_path.c_str())) {
1348 // Delete the b_path so we don't try again (or fail earlier).
1349 if (unlink(b_path.c_str()) != 0) {
1350 PLOG(ERROR) << "Could not unlink " << b_path;
1351 }
1352
1353 return false;
1354 }
1355
1356 return true;
1357}
1358
1359bool move_ab(const char* apk_path, const char* instruction_set, const char* oat_dir) {
1360 // Get the current slot suffix. No suffix, no A/B.
1361 std::string slot_suffix;
1362 {
1363 char buf[kPropertyValueMax];
1364 if (get_property("ro.boot.slot_suffix", buf, nullptr) <= 0) {
1365 return false;
1366 }
1367 slot_suffix = buf;
1368
1369 if (!ValidateTargetSlotSuffix(slot_suffix)) {
1370 LOG(ERROR) << "Target slot suffix not legal: " << slot_suffix;
1371 return false;
1372 }
1373 }
1374
1375 // Validate other inputs.
1376 if (validate_apk_path(apk_path) != 0) {
1377 LOG(ERROR) << "Invalid apk_path: " << apk_path;
1378 return false;
1379 }
1380 if (validate_apk_path(oat_dir) != 0) {
1381 LOG(ERROR) << "Invalid oat_dir: " << oat_dir;
1382 return false;
1383 }
1384
1385 char a_path[PKG_PATH_MAX];
1386 if (!calculate_oat_file_path(a_path, oat_dir, apk_path, instruction_set)) {
1387 return false;
1388 }
1389 const std::string a_vdex_path = create_vdex_filename(a_path);
1390 const std::string a_image_path = create_image_filename(a_path);
1391
1392 // B path = A path + slot suffix.
1393 const std::string b_path = StringPrintf("%s.%s", a_path, slot_suffix.c_str());
1394 const std::string b_vdex_path = StringPrintf("%s.%s", a_vdex_path.c_str(), slot_suffix.c_str());
1395 const std::string b_image_path = StringPrintf("%s.%s",
1396 a_image_path.c_str(),
1397 slot_suffix.c_str());
1398
1399 bool success = true;
1400 if (move_ab_path(b_path, a_path)) {
1401 if (move_ab_path(b_vdex_path, a_vdex_path)) {
1402 // Note: we can live without an app image. As such, ignore failure to move the image file.
1403 // If we decide to require the app image, or the app image being moved correctly,
1404 // then change accordingly.
1405 constexpr bool kIgnoreAppImageFailure = true;
1406
1407 if (!a_image_path.empty()) {
1408 if (!move_ab_path(b_image_path, a_image_path)) {
1409 unlink(a_image_path.c_str());
1410 if (!kIgnoreAppImageFailure) {
1411 success = false;
1412 }
1413 }
1414 }
1415 } else {
1416 // Cleanup: delete B image, ignore errors.
1417 unlink(b_image_path.c_str());
1418 success = false;
1419 }
1420 } else {
1421 // Cleanup: delete B image, ignore errors.
1422 unlink(b_vdex_path.c_str());
1423 unlink(b_image_path.c_str());
1424 success = false;
1425 }
1426 return success;
1427}
1428
1429bool delete_odex(const char* apk_path, const char* instruction_set, const char* oat_dir) {
1430 // Delete the oat/odex file.
1431 char out_path[PKG_PATH_MAX];
1432 if (!create_oat_out_path(apk_path, instruction_set, oat_dir, out_path)) {
1433 return false;
1434 }
1435
1436 // In case of a permission failure report the issue. Otherwise just print a warning.
1437 auto unlink_and_check = [](const char* path) -> bool {
1438 int result = unlink(path);
1439 if (result != 0) {
1440 if (errno == EACCES || errno == EPERM) {
1441 PLOG(ERROR) << "Could not unlink " << path;
1442 return false;
1443 }
1444 PLOG(WARNING) << "Could not unlink " << path;
1445 }
1446 return true;
1447 };
1448
1449 // Delete the oat/odex file.
1450 bool return_value_oat = unlink_and_check(out_path);
1451
1452 // Derive and delete the app image.
1453 bool return_value_art = unlink_and_check(create_image_filename(out_path).c_str());
1454
1455 // Report success.
1456 return return_value_oat && return_value_art;
1457}
1458
Jeff Sharkey6c2c0562016-12-07 12:12:00 -07001459int dexopt(const char* const params[DEXOPT_PARAM_COUNT]) {
1460 return dexopt(params[0], // apk_path
1461 atoi(params[1]), // uid
1462 params[2], // pkgname
1463 params[3], // instruction_set
1464 atoi(params[4]), // dexopt_needed
1465 params[5], // oat_dir
1466 atoi(params[6]), // dexopt_flags
1467 params[7], // compiler_filter
1468 parse_null(params[8]), // volume_uuid
1469 parse_null(params[9])); // shared_libraries
1470 static_assert(DEXOPT_PARAM_COUNT == 10U, "Unexpected dexopt param count");
1471}
1472
1473} // namespace installd
1474} // namespace android