1 /* 2 * Copyright (C) 2020 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 "incremental.h" 18 19 #include "incremental_utils.h" 20 21 #include <android-base/file.h> 22 #include <android-base/stringprintf.h> 23 #include <openssl/base64.h> 24 25 #include "adb_client.h" 26 #include "adb_utils.h" 27 #include "commandline.h" 28 #include "sysdeps.h" 29 30 using namespace std::literals; 31 32 namespace incremental { 33 34 using android::base::StringPrintf; 35 36 // Read, verify and return the signature bytes. Keeping fd at the position of start of verity tree. 37 static std::pair<unique_fd, std::vector<char>> read_signature(Size file_size, 38 std::string signature_file, 39 bool silent) { 40 signature_file += IDSIG; 41 42 struct stat st; 43 if (stat(signature_file.c_str(), &st)) { 44 if (!silent) { 45 fprintf(stderr, "Failed to stat signature file %s.\n", signature_file.c_str()); 46 } 47 return {}; 48 } 49 50 unique_fd fd(adb_open(signature_file.c_str(), O_RDONLY)); 51 if (fd < 0) { 52 if (!silent) { 53 fprintf(stderr, "Failed to open signature file: %s.\n", signature_file.c_str()); 54 } 55 return {}; 56 } 57 58 auto [signature, tree_size] = read_id_sig_headers(fd); 59 60 std::vector<char> invalid_signature; 61 if (signature.empty()) { 62 if (!silent) { 63 fprintf(stderr, "Invalid signature format. Abort.\n"); 64 } 65 return {std::move(fd), std::move(invalid_signature)}; 66 } 67 if (signature.size() > kMaxSignatureSize) { 68 if (!silent) { 69 fprintf(stderr, "Signature is too long: %lld. Max allowed is %d. Abort.\n", 70 (long long)signature.size(), kMaxSignatureSize); 71 } 72 return {std::move(fd), std::move(invalid_signature)}; 73 } 74 75 if (auto expected = verity_tree_size_for_file(file_size); tree_size != expected) { 76 if (!silent) { 77 fprintf(stderr, 78 "Verity tree size mismatch in signature file: %s [was %lld, expected %lld].\n", 79 signature_file.c_str(), (long long)tree_size, (long long)expected); 80 } 81 return {std::move(fd), std::move(invalid_signature)}; 82 } 83 84 return {std::move(fd), std::move(signature)}; 85 } 86 87 // Base64-encode signature bytes. Keeping fd at the position of start of verity tree. 88 static std::pair<unique_fd, std::string> read_and_encode_signature(Size file_size, 89 std::string signature_file, 90 bool silent) { 91 std::string encoded_signature; 92 93 auto [fd, signature] = read_signature(file_size, std::move(signature_file), silent); 94 if (!fd.ok() || signature.empty()) { 95 return {std::move(fd), std::move(encoded_signature)}; 96 } 97 98 size_t base64_len = 0; 99 if (!EVP_EncodedLength(&base64_len, signature.size())) { 100 if (!silent) { 101 fprintf(stderr, "Fail to estimate base64 encoded length. Abort.\n"); 102 } 103 return {std::move(fd), std::move(encoded_signature)}; 104 } 105 106 encoded_signature.resize(base64_len, '\0'); 107 encoded_signature.resize(EVP_EncodeBlock((uint8_t*)encoded_signature.data(), 108 (const uint8_t*)signature.data(), signature.size())); 109 110 return {std::move(fd), std::move(encoded_signature)}; 111 } 112 113 // Send install-incremental to the device along with properly configured file descriptors in 114 // streaming format. Once connection established, send all fs-verity tree bytes. 115 static unique_fd start_install(const Files& files, const Args& passthrough_args, bool silent) { 116 std::vector<std::string> command_args{"package", "install-incremental"}; 117 command_args.insert(command_args.end(), passthrough_args.begin(), passthrough_args.end()); 118 119 for (int i = 0, size = files.size(); i < size; ++i) { 120 const auto& file = files[i]; 121 122 struct stat st; 123 if (stat(file.c_str(), &st)) { 124 if (!silent) { 125 fprintf(stderr, "Failed to stat input file %s. Abort.\n", file.c_str()); 126 } 127 return {}; 128 } 129 130 auto [signature_fd, signature] = read_and_encode_signature(st.st_size, file, silent); 131 if (signature_fd.ok() && signature.empty()) { 132 return {}; 133 } 134 135 auto file_desc = StringPrintf("%s:%lld:%d:%s:1", android::base::Basename(file).c_str(), 136 (long long)st.st_size, i, signature.c_str()); 137 command_args.push_back(std::move(file_desc)); 138 } 139 140 std::string error; 141 auto connection_fd = unique_fd(send_abb_exec_command(command_args, &error)); 142 if (connection_fd < 0) { 143 if (!silent) { 144 fprintf(stderr, "Failed to run: %s, error: %s\n", 145 android::base::Join(command_args, " ").c_str(), error.c_str()); 146 } 147 return {}; 148 } 149 150 return connection_fd; 151 } 152 153 bool can_install(const Files& files) { 154 for (const auto& file : files) { 155 struct stat st; 156 if (stat(file.c_str(), &st)) { 157 return false; 158 } 159 160 if (android::base::EndsWithIgnoreCase(file, ".apk")) { 161 // Signature has to be present for APKs. 162 auto [fd, _] = read_signature(st.st_size, file, /*silent=*/true); 163 if (!fd.ok()) { 164 return false; 165 } 166 } 167 } 168 return true; 169 } 170 171 std::optional<Process> install(const Files& files, const Args& passthrough_args, bool silent) { 172 auto connection_fd = start_install(files, passthrough_args, silent); 173 if (connection_fd < 0) { 174 if (!silent) { 175 fprintf(stderr, "adb: failed to initiate installation on device.\n"); 176 } 177 return {}; 178 } 179 180 std::string adb_path = android::base::GetExecutablePath(); 181 182 auto osh = cast_handle_to_int(adb_get_os_handle(connection_fd.get())); 183 auto fd_param = std::to_string(osh); 184 185 // pipe for child process to write output 186 int print_fds[2]; 187 if (adb_socketpair(print_fds) != 0) { 188 if (!silent) { 189 fprintf(stderr, "adb: failed to create socket pair for child to print to parent\n"); 190 } 191 return {}; 192 } 193 auto [pipe_read_fd, pipe_write_fd] = print_fds; 194 auto pipe_write_fd_param = std::to_string(cast_handle_to_int(adb_get_os_handle(pipe_write_fd))); 195 close_on_exec(pipe_read_fd); 196 197 std::vector<std::string> args(std::move(files)); 198 args.insert(args.begin(), {"inc-server", fd_param, pipe_write_fd_param}); 199 auto child = 200 adb_launch_process(adb_path, std::move(args), {connection_fd.get(), pipe_write_fd}); 201 if (!child) { 202 if (!silent) { 203 fprintf(stderr, "adb: failed to fork: %s\n", strerror(errno)); 204 } 205 return {}; 206 } 207 208 adb_close(pipe_write_fd); 209 210 auto killOnExit = [](Process* p) { p->kill(); }; 211 std::unique_ptr<Process, decltype(killOnExit)> serverKiller(&child, killOnExit); 212 213 Result result = wait_for_installation(pipe_read_fd); 214 adb_close(pipe_read_fd); 215 216 if (result != Result::Success) { 217 if (!silent) { 218 fprintf(stderr, "adb: install command failed"); 219 } 220 return {}; 221 } 222 223 // adb client exits now but inc-server can continue 224 serverKiller.release(); 225 return child; 226 } 227 228 Result wait_for_installation(int read_fd) { 229 static constexpr int maxMessageSize = 256; 230 std::vector<char> child_stdout(CHUNK_SIZE); 231 int bytes_read; 232 int buf_size = 0; 233 // TODO(b/150865433): optimize child's output parsing 234 while ((bytes_read = adb_read(read_fd, child_stdout.data() + buf_size, 235 child_stdout.size() - buf_size)) > 0) { 236 // print to parent's stdout 237 fprintf(stdout, "%.*s", bytes_read, child_stdout.data() + buf_size); 238 239 buf_size += bytes_read; 240 const std::string_view stdout_str(child_stdout.data(), buf_size); 241 // wait till installation either succeeds or fails 242 if (stdout_str.find("Success") != std::string::npos) { 243 return Result::Success; 244 } 245 // on failure, wait for full message 246 static constexpr auto failure_msg_head = "Failure ["sv; 247 if (const auto begin_itr = stdout_str.find(failure_msg_head); 248 begin_itr != std::string::npos) { 249 if (buf_size >= maxMessageSize) { 250 return Result::Failure; 251 } 252 const auto end_itr = stdout_str.rfind("]"); 253 if (end_itr != std::string::npos && end_itr >= begin_itr + failure_msg_head.size()) { 254 return Result::Failure; 255 } 256 } 257 child_stdout.resize(buf_size + CHUNK_SIZE); 258 } 259 return Result::None; 260 } 261 262 } // namespace incremental 263