blob: 8c000a11c92386d314453cdabd5652f1a6333766 [file] [log] [blame]
Eric Holk2af5e6a2019-01-09 18:17:27 -08001/*
2 * Copyright (C) 2019 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 "view_compiler.h"
18
19#include <string>
20
21#include <fcntl.h>
22#include <sys/stat.h>
23#include <sys/types.h>
24#include <sys/wait.h>
25#include <unistd.h>
26
27#include "utils.h"
28
29#include "android-base/logging.h"
30#include "android-base/stringprintf.h"
31#include "android-base/unique_fd.h"
32
33namespace android {
34namespace installd {
35
Jiakai Zhang0a7603c2022-02-21 19:38:14 +000036namespace {
37
38using ::android::base::unique_fd;
39
40constexpr int kTimeoutMs = 300000;
41
42} // namespace
Eric Holk2af5e6a2019-01-09 18:17:27 -080043
44bool view_compiler(const char* apk_path, const char* package_name, const char* out_dex_file,
45 int uid) {
46 CHECK(apk_path != nullptr);
47 CHECK(package_name != nullptr);
48 CHECK(out_dex_file != nullptr);
49
50 // viewcompiler won't have permission to open anything, so we have to open the files first
51 // and pass file descriptors.
52
53 // Open input file
Nick Kralevich9bb358f2019-04-01 09:08:53 -070054 unique_fd infd{open(apk_path, O_RDONLY)}; // NOLINT(android-cloexec-open)
Eric Holk2af5e6a2019-01-09 18:17:27 -080055 if (infd.get() < 0) {
56 PLOG(ERROR) << "Could not open input file: " << apk_path;
57 return false;
58 }
59
60 // Set up output file. viewcompiler can't open outputs by fd, but it can write to stdout, so
61 // we close stdout and open it towards the right output.
Nick Kralevich9bb358f2019-04-01 09:08:53 -070062 unique_fd outfd{open(out_dex_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644)};
Eric Holk2af5e6a2019-01-09 18:17:27 -080063 if (outfd.get() < 0) {
64 PLOG(ERROR) << "Could not open output file: " << out_dex_file;
65 return false;
66 }
67 if (fchmod(outfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) != 0) {
68 PLOG(ERROR) << "Could not change output file permissions";
69 return false;
70 }
Eric Holk2af5e6a2019-01-09 18:17:27 -080071 if (dup2(outfd, STDOUT_FILENO) < 0) {
72 PLOG(ERROR) << "Could not duplicate output file descriptor";
73 return false;
74 }
75
76 // Prepare command line arguments for viewcompiler
77 std::string args[] = {"/system/bin/viewcompiler",
78 "--apk",
79 "--infd",
80 android::base::StringPrintf("%d", infd.get()),
81 "--dex",
82 "--package",
83 package_name};
84 char* const argv[] = {const_cast<char*>(args[0].c_str()), const_cast<char*>(args[1].c_str()),
85 const_cast<char*>(args[2].c_str()), const_cast<char*>(args[3].c_str()),
86 const_cast<char*>(args[4].c_str()), const_cast<char*>(args[5].c_str()),
87 const_cast<char*>(args[6].c_str()), nullptr};
88
89 pid_t pid = fork();
90 if (pid == 0) {
91 // Now that we've opened the files we need, drop privileges.
92 drop_capabilities(uid);
93 execv("/system/bin/viewcompiler", argv);
94 _exit(1);
95 }
96
Jiakai Zhang0a7603c2022-02-21 19:38:14 +000097 int return_code = wait_child_with_timeout(pid, kTimeoutMs);
98 if (!WIFEXITED(return_code)) {
99 LOG(WARNING) << "viewcompiler failed for " << package_name << ":" << apk_path;
100 if (WTERMSIG(return_code) == SIGKILL) {
101 // If the subprocess is killed while it's writing to the file, the file is likely
102 // corrupted, so we should remove it.
103 remove_file_at_fd(outfd.get());
104 }
105 return false;
106 }
107 return WEXITSTATUS(return_code) == 0;
Eric Holk2af5e6a2019-01-09 18:17:27 -0800108}
109
110} // namespace installd
Nick Kralevich9bb358f2019-04-01 09:08:53 -0700111} // namespace android