blob: 65a83a695296c0e53db0fc8490f140369637d68e [file] [log] [blame]
Dees Troy3be70a82013-10-22 14:25:12 +00001/*
bigbiff bigbiff19fb79c2016-09-05 21:04:51 -04002 Copyright 2012 to 2017 bigbiff/Dees_Troy TeamWin
Dees Troy3be70a82013-10-22 14:25:12 +00003 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
Dees_Troy32c8eb82012-09-11 15:28:06 -040018
nkk71b4c35912017-10-11 23:39:10 +030019
20#ifndef _GNU_SOURCE
21#define _GNU_SOURCE
22#endif
23
Dees_Troy32c8eb82012-09-11 15:28:06 -040024#include <ctype.h>
25#include <errno.h>
26#include <fcntl.h>
27#include <limits.h>
nkk71b4c35912017-10-11 23:39:10 +030028#include <sys/mman.h>
Dees_Troy32c8eb82012-09-11 15:28:06 -040029#include <sys/stat.h>
30#include <sys/wait.h>
Chaosmaster6c1477d2020-02-03 15:54:32 +010031#include <sys/mount.h>
Dees_Troy32c8eb82012-09-11 15:28:06 -040032#include <unistd.h>
33
34#include <string.h>
35#include <stdio.h>
Ethan Yonker193befe2019-04-02 16:01:31 -050036#include <cutils/properties.h>
Dees_Troy32c8eb82012-09-11 15:28:06 -040037
bigbiff1f9e4842020-10-31 11:33:15 -040038#include <android-base/unique_fd.h>
39
Dees_Troy2673cec2013-04-02 20:22:16 +000040#include "twcommon.h"
Ethan Yonker75bf0412014-11-21 13:54:27 -060041#include "mtdutils/mounts.h"
42#include "mtdutils/mtdutils.h"
Ethan Yonker8373cfe2017-09-08 06:50:54 -050043
bigbiffd58ba182020-03-23 10:02:29 -040044#include "otautil/sysutil.h"
Ethan Yonker8373cfe2017-09-08 06:50:54 -050045#include <ziparchive/zip_archive.h>
bigbiff1f9e4842020-10-31 11:33:15 -040046#include "twinstall/install.h"
47#include "twinstall/verifier.h"
Dees_Troy32c8eb82012-09-11 15:28:06 -040048#include "variables.h"
49#include "data.hpp"
50#include "partitions.hpp"
bigbiff bigbiff56cf5642016-08-19 17:43:45 -040051#include "twrpDigestDriver.hpp"
52#include "twrpDigest/twrpDigest.hpp"
53#include "twrpDigest/twrpMD5.hpp"
Dees_Troy38bd7602012-09-14 13:33:53 -040054#include "twrp-functions.hpp"
Ethan Yonker74db1572015-10-28 12:44:49 -050055#include "gui/gui.hpp"
Ethan Yonker20eb0bc2016-03-22 14:23:28 -050056#include "gui/pages.hpp"
Ethan Yonkerf1179622016-08-25 15:32:21 -050057#include "legacy_property_service.h"
Ethan Yonker941a8992016-12-05 09:04:30 -060058#include "twinstall.h"
59#include "installcommand.h"
Dees_Troy2673cec2013-04-02 20:22:16 +000060extern "C" {
61 #include "gui/gui.h"
that7e303cf2014-03-06 07:57:43 +010062}
63
Ethan Yonker941a8992016-12-05 09:04:30 -060064#define AB_OTA "payload_properties.txt"
65
lambdadroidc4faea82018-09-26 22:56:51 +020066#ifndef TW_NO_LEGACY_PROPS
that7e303cf2014-03-06 07:57:43 +010067static const char* properties_path = "/dev/__properties__";
68static const char* properties_path_renamed = "/dev/__properties_kk__";
Matt Mowercdd3b332014-03-27 14:38:48 -050069static bool legacy_props_env_initd = false;
70static bool legacy_props_path_modified = false;
lambdadroidc4faea82018-09-26 22:56:51 +020071#endif
that7e303cf2014-03-06 07:57:43 +010072
Ethan Yonker941a8992016-12-05 09:04:30 -060073enum zip_type {
74 UNKNOWN_ZIP_TYPE = 0,
75 UPDATE_BINARY_ZIP_TYPE,
76 AB_OTA_ZIP_TYPE,
77 TWRP_THEME_ZIP_TYPE
78};
79
lambdadroidc4faea82018-09-26 22:56:51 +020080#ifndef TW_NO_LEGACY_PROPS
that50640482015-08-30 12:08:05 +020081// to support pre-KitKat update-binaries that expect properties in the legacy format
Matt Mowercdd3b332014-03-27 14:38:48 -050082static int switch_to_legacy_properties()
that7e303cf2014-03-06 07:57:43 +010083{
Matt Mowercdd3b332014-03-27 14:38:48 -050084 if (!legacy_props_env_initd) {
85 if (legacy_properties_init() != 0)
86 return -1;
87
88 char tmp[32];
89 int propfd, propsz;
90 legacy_get_property_workspace(&propfd, &propsz);
91 sprintf(tmp, "%d,%d", dup(propfd), propsz);
92 setenv("ANDROID_PROPERTY_WORKSPACE", tmp, 1);
93 legacy_props_env_initd = true;
94 }
that7e303cf2014-03-06 07:57:43 +010095
96 if (TWFunc::Path_Exists(properties_path)) {
97 // hide real properties so that the updater uses the envvar to find the legacy format properties
Matt Mowercdd3b332014-03-27 14:38:48 -050098 if (rename(properties_path, properties_path_renamed) != 0) {
99 LOGERR("Renaming %s failed: %s\n", properties_path, strerror(errno));
100 return -1;
101 } else {
102 legacy_props_path_modified = true;
103 }
that7e303cf2014-03-06 07:57:43 +0100104 }
Matt Mowercdd3b332014-03-27 14:38:48 -0500105
106 return 0;
that7e303cf2014-03-06 07:57:43 +0100107}
108
Matt Mowercdd3b332014-03-27 14:38:48 -0500109static int switch_to_new_properties()
that7e303cf2014-03-06 07:57:43 +0100110{
111 if (TWFunc::Path_Exists(properties_path_renamed)) {
Matt Mowercdd3b332014-03-27 14:38:48 -0500112 if (rename(properties_path_renamed, properties_path) != 0) {
113 LOGERR("Renaming %s failed: %s\n", properties_path_renamed, strerror(errno));
114 return -1;
115 } else {
116 legacy_props_path_modified = false;
117 }
that7e303cf2014-03-06 07:57:43 +0100118 }
Matt Mowercdd3b332014-03-27 14:38:48 -0500119
120 return 0;
Dees_Troy2673cec2013-04-02 20:22:16 +0000121}
lambdadroidc4faea82018-09-26 22:56:51 +0200122#endif
Dees_Troy32c8eb82012-09-11 15:28:06 -0400123
bigbiff1f9e4842020-10-31 11:33:15 -0400124static int Install_Theme(const char* path, ZipArchiveHandle Zip) {
Ethan Yonker20eb0bc2016-03-22 14:23:28 -0500125#ifdef TW_OEM_BUILD // We don't do custom themes in OEM builds
bigbiff1f9e4842020-10-31 11:33:15 -0400126 CloseArchive(Zip);
Ethan Yonker20eb0bc2016-03-22 14:23:28 -0500127 return INSTALL_CORRUPT;
128#else
bigbiff1f9e4842020-10-31 11:33:15 -0400129 ZipString binary_name("ui.xml");
130 ZipEntry binary_entry;
131 if (FindEntry(Zip, binary_name, &binary_entry) != 0) {
132 CloseArchive(Zip);
Ethan Yonker20eb0bc2016-03-22 14:23:28 -0500133 return INSTALL_CORRUPT;
134 }
135 if (!PartitionManager.Mount_Settings_Storage(true))
136 return INSTALL_ERROR;
137 string theme_path = DataManager::GetSettingsStoragePath();
138 theme_path += "/TWRP/theme";
139 if (!TWFunc::Path_Exists(theme_path)) {
140 if (!TWFunc::Recursive_Mkdir(theme_path)) {
141 return INSTALL_ERROR;
142 }
143 }
144 theme_path += "/ui.zip";
145 if (TWFunc::copy_file(path, theme_path, 0644) != 0) {
146 return INSTALL_ERROR;
147 }
148 LOGINFO("Installing custom theme '%s' to '%s'\n", path, theme_path.c_str());
149 PageManager::RequestReload();
150 return INSTALL_SUCCESS;
151#endif
152}
153
bigbiff1f9e4842020-10-31 11:33:15 -0400154static int Prepare_Update_Binary(ZipArchiveHandle Zip) {
Ethan Yonker193befe2019-04-02 16:01:31 -0500155 char arches[PATH_MAX];
Ethan Yonker193befe2019-04-02 16:01:31 -0500156 property_get("ro.product.cpu.abilist", arches, "error");
157 if (strcmp(arches, "error") == 0)
158 property_get("ro.product.cpu.abi", arches, "error");
159 vector<string> split = TWFunc::split_string(arches, ',', true);
160 std::vector<string>::iterator arch;
bigbiff1f9e4842020-10-31 11:33:15 -0400161 std::string base_name = UPDATE_BINARY_NAME;
Ethan Yonker193befe2019-04-02 16:01:31 -0500162 base_name += "-";
bigbiff1f9e4842020-10-31 11:33:15 -0400163 ZipEntry binary_entry;
164 ZipString update_binary_string(UPDATE_BINARY_NAME);
165 if (FindEntry(Zip, update_binary_string, &binary_entry) != 0) {
166 for (arch = split.begin(); arch != split.end(); arch++) {
167 std::string temp = base_name + *arch;
168 ZipString binary_name(temp.c_str());
169 if (FindEntry(Zip, binary_name, &binary_entry) != 0) {
170 ZipString binary_name(temp.c_str());
171 break;
172 }
Ethan Yonker193befe2019-04-02 16:01:31 -0500173 }
174 }
bigbiff1f9e4842020-10-31 11:33:15 -0400175 LOGINFO("Extracting updater binary '%s'\n", UPDATE_BINARY_NAME);
176 unlink(TMP_UPDATER_BINARY_PATH);
177 android::base::unique_fd fd(
178 open(TMP_UPDATER_BINARY_PATH, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0755));
179 if (fd == -1) {
180 return INSTALL_ERROR;
181 }
182 int32_t err = ExtractEntryToFile(Zip, &binary_entry, fd);
183 if (err != 0) {
184 CloseArchive(Zip);
185 LOGERR("Could not extract '%s'\n", UPDATE_BINARY_NAME);
Dees_Troy2673cec2013-04-02 20:22:16 +0000186 return INSTALL_ERROR;
187 }
Dees_Troy32c8eb82012-09-11 15:28:06 -0400188
Dees_Troy512376c2013-09-03 19:39:41 +0000189 // If exists, extract file_contexts from the zip file
bigbiff1f9e4842020-10-31 11:33:15 -0400190 ZipString file_contexts("file_contexts");
191 ZipEntry file_contexts_entry;
192 if (FindEntry(Zip, file_contexts, &file_contexts_entry) != 0) {
Dees_Troy512376c2013-09-03 19:39:41 +0000193 LOGINFO("Zip does not contain SELinux file_contexts file in its root.\n");
194 } else {
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500195 const string output_filename = "/file_contexts";
Dees_Troy512376c2013-09-03 19:39:41 +0000196 LOGINFO("Zip contains SELinux file_contexts file in its root. Extracting to %s\n", output_filename.c_str());
bigbiff1f9e4842020-10-31 11:33:15 -0400197 android::base::unique_fd fd(
198 open(output_filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0644));
199 if (fd == -1) {
200 return INSTALL_ERROR;
201 }
202 if (ExtractEntryToFile(Zip, &file_contexts_entry, fd)) {
203 CloseArchive(Zip);
that50640482015-08-30 12:08:05 +0200204 LOGERR("Could not extract '%s'\n", output_filename.c_str());
Dees_Troy512376c2013-09-03 19:39:41 +0000205 return INSTALL_ERROR;
206 }
207 }
Ethan Yonker941a8992016-12-05 09:04:30 -0600208 return INSTALL_SUCCESS;
209}
210
lambdadroidc4faea82018-09-26 22:56:51 +0200211#ifndef TW_NO_LEGACY_PROPS
nkk71b4c35912017-10-11 23:39:10 +0300212static bool update_binary_has_legacy_properties(const char *binary) {
213 const char str_to_match[] = "ANDROID_PROPERTY_WORKSPACE";
214 int len_to_match = sizeof(str_to_match) - 1;
215 bool found = false;
216
217 int fd = open(binary, O_RDONLY);
218 if (fd < 0) {
219 LOGINFO("has_legacy_properties: Could not open %s: %s!\n", binary, strerror(errno));
220 return false;
221 }
222
223 struct stat finfo;
224 if (fstat(fd, &finfo) < 0) {
225 LOGINFO("has_legacy_properties: Could not fstat %d: %s!\n", fd, strerror(errno));
226 close(fd);
227 return false;
228 }
229
230 void *data = mmap(NULL, finfo.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
231 if (data == MAP_FAILED) {
Simon Shi8ae2b0d2019-03-09 13:01:55 +0800232 LOGINFO("has_legacy_properties: mmap (size=%zu) failed: %s!\n", (size_t)finfo.st_size, strerror(errno));
nkk71b4c35912017-10-11 23:39:10 +0300233 } else {
234 if (memmem(data, finfo.st_size, str_to_match, len_to_match)) {
235 LOGINFO("has_legacy_properties: Found legacy property match!\n");
236 found = true;
237 }
238 munmap(data, finfo.st_size);
239 }
240 close(fd);
241
242 return found;
243}
lambdadroidc4faea82018-09-26 22:56:51 +0200244#endif
nkk71b4c35912017-10-11 23:39:10 +0300245
bigbiff1f9e4842020-10-31 11:33:15 -0400246static int Run_Update_Binary(const char *path, int* wipe_cache, zip_type ztype) {
Ethan Yonker941a8992016-12-05 09:04:30 -0600247 int ret_val, pipe_fd[2], status, zip_verify;
248 char buffer[1024];
249 FILE* child_data;
Dees_Troy512376c2013-09-03 19:39:41 +0000250
Matt Mower6883d732014-03-20 17:28:13 -0500251#ifndef TW_NO_LEGACY_PROPS
nkk71b4c35912017-10-11 23:39:10 +0300252 if (!update_binary_has_legacy_properties(TMP_UPDATER_BINARY_PATH)) {
253 LOGINFO("Legacy property environment not used in updater.\n");
254 } else if (switch_to_legacy_properties() != 0) { /* Set legacy properties */
255 LOGERR("Legacy property environment did not initialize successfully. Properties may not be detected.\n");
256 } else {
257 LOGINFO("Legacy property environment initialized.\n");
Matt Mowercdd3b332014-03-27 14:38:48 -0500258 }
Matt Mower6883d732014-03-20 17:28:13 -0500259#endif
Matt Mowercdd3b332014-03-27 14:38:48 -0500260
Dees_Troy2673cec2013-04-02 20:22:16 +0000261 pipe(pipe_fd);
Dees_Troy32c8eb82012-09-11 15:28:06 -0400262
Ethan Yonker941a8992016-12-05 09:04:30 -0600263 std::vector<std::string> args;
264 if (ztype == UPDATE_BINARY_ZIP_TYPE) {
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500265 ret_val = update_binary_command(path, 0, pipe_fd[1], &args);
Ethan Yonker941a8992016-12-05 09:04:30 -0600266 } else if (ztype == AB_OTA_ZIP_TYPE) {
bigbiff1f9e4842020-10-31 11:33:15 -0400267 ret_val = abupdate_binary_command(path, 0, pipe_fd[1], &args);
Ethan Yonker941a8992016-12-05 09:04:30 -0600268 } else {
269 LOGERR("Unknown zip type %i\n", ztype);
270 ret_val = INSTALL_CORRUPT;
271 }
272 if (ret_val) {
273 close(pipe_fd[0]);
274 close(pipe_fd[1]);
275 return ret_val;
276 }
277
278 // Convert the vector to a NULL-terminated char* array suitable for execv.
279 const char* chr_args[args.size() + 1];
280 chr_args[args.size()] = NULL;
281 for (size_t i = 0; i < args.size(); i++)
282 chr_args[i] = args[i].c_str();
Dees_Troy32c8eb82012-09-11 15:28:06 -0400283
Dees_Troy2673cec2013-04-02 20:22:16 +0000284 pid_t pid = fork();
285 if (pid == 0) {
286 close(pipe_fd[0]);
Ethan Yonker941a8992016-12-05 09:04:30 -0600287 execve(chr_args[0], const_cast<char**>(chr_args), environ);
288 printf("E:Can't execute '%s': %s\n", chr_args[0], strerror(errno));
Dees_Troy2673cec2013-04-02 20:22:16 +0000289 _exit(-1);
290 }
291 close(pipe_fd[1]);
Dees_Troy32c8eb82012-09-11 15:28:06 -0400292
Dees_Troy2673cec2013-04-02 20:22:16 +0000293 *wipe_cache = 0;
Dees_Troy32c8eb82012-09-11 15:28:06 -0400294
Dees_Troy2673cec2013-04-02 20:22:16 +0000295 DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
296 child_data = fdopen(pipe_fd[0], "r");
297 while (fgets(buffer, sizeof(buffer), child_data) != NULL) {
298 char* command = strtok(buffer, " \n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200299 if (command == NULL) {
300 continue;
301 } else if (strcmp(command, "progress") == 0) {
302 char* fraction_char = strtok(NULL, " \n");
303 char* seconds_char = strtok(NULL, " \n");
Dees_Troy32c8eb82012-09-11 15:28:06 -0400304
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200305 float fraction_float = strtof(fraction_char, NULL);
306 int seconds_float = strtol(seconds_char, NULL, 10);
Dees_Troy32c8eb82012-09-11 15:28:06 -0400307
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200308 if (zip_verify)
bigbiff1f9e4842020-10-31 11:33:15 -0400309 DataManager::ShowProgress(fraction_float * (1 - VERIFICATION_PROGRESS_FRACTION), seconds_float);
Dees_Troy2673cec2013-04-02 20:22:16 +0000310 else
311 DataManager::ShowProgress(fraction_float, seconds_float);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200312 } else if (strcmp(command, "set_progress") == 0) {
313 char* fraction_char = strtok(NULL, " \n");
314 float fraction_float = strtof(fraction_char, NULL);
Chaosmasterd5364a02020-02-03 15:38:02 +0100315 DataManager::_SetProgress(fraction_float);
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200316 } else if (strcmp(command, "ui_print") == 0) {
317 char* display_value = strtok(NULL, "\n");
318 if (display_value) {
319 gui_print("%s", display_value);
320 } else {
321 gui_print("\n");
322 }
323 } else if (strcmp(command, "wipe_cache") == 0) {
324 *wipe_cache = 1;
325 } else if (strcmp(command, "clear_display") == 0) {
326 // Do nothing, not supported by TWRP
Ethan Yonker072c8d82016-08-26 22:22:24 -0500327 } else if (strcmp(command, "log") == 0) {
328 printf("%s\n", strtok(NULL, "\n"));
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200329 } else {
330 LOGERR("unknown command [%s]\n", command);
331 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000332 }
333 fclose(child_data);
Dees_Troy32c8eb82012-09-11 15:28:06 -0400334
that50640482015-08-30 12:08:05 +0200335 int waitrc = TWFunc::Wait_For_Child(pid, &status, "Updater");
Matt Mowercdd3b332014-03-27 14:38:48 -0500336
Matt Mower6883d732014-03-20 17:28:13 -0500337#ifndef TW_NO_LEGACY_PROPS
nkk71b4c35912017-10-11 23:39:10 +0300338 /* Unset legacy properties */
339 if (legacy_props_path_modified) {
340 if (switch_to_new_properties() != 0) {
341 LOGERR("Legacy property environment did not disable successfully. Legacy properties may still be in use.\n");
342 } else {
343 LOGINFO("Legacy property environment disabled.\n");
Matt Mowercdd3b332014-03-27 14:38:48 -0500344 }
345 }
Matt Mower6883d732014-03-20 17:28:13 -0500346#endif
Matt Mowercdd3b332014-03-27 14:38:48 -0500347
that50640482015-08-30 12:08:05 +0200348 if (waitrc != 0)
Dees_Troy2673cec2013-04-02 20:22:16 +0000349 return INSTALL_ERROR;
Dees_Troy32c8eb82012-09-11 15:28:06 -0400350
Dees_Troy2673cec2013-04-02 20:22:16 +0000351 return INSTALL_SUCCESS;
Dees_Troy32c8eb82012-09-11 15:28:06 -0400352}
353
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500354int TWinstall_zip(const char* path, int* wipe_cache) {
Chaosmasterff4f9582020-01-26 15:38:11 +0100355 int ret_val, zip_verify = 1, unmount_system = 1;
Dees_Troy32c8eb82012-09-11 15:28:06 -0400356
Ethan Yonker74db1572015-10-28 12:44:49 -0500357 gui_msg(Msg("installing_zip=Installing zip file '{1}'")(path));
Ethan Yonker24813422014-11-07 17:19:07 -0600358 if (strlen(path) < 9 || strncmp(path, "/sideload", 9) != 0) {
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400359 string digest_str;
360 string Full_Filename = path;
bigbiff bigbiff56cf5642016-08-19 17:43:45 -0400361
362 gui_msg("check_for_digest=Checking for Digest file...");
bigbiff bigbiff718ab392019-03-28 19:46:56 -0400363
Ethan Yonker1da568f2019-04-09 15:29:51 -0500364 if (*path != '@' && !twrpDigestDriver::Check_File_Digest(Full_Filename)) {
365 LOGERR("Aborting zip install: Digest verification failed\n");
366 return INSTALL_CORRUPT;
Ethan Yonker24813422014-11-07 17:19:07 -0600367 }
368 }
369
Chaosmasterff4f9582020-01-26 15:38:11 +0100370 DataManager::GetValue(TW_UNMOUNT_SYSTEM, unmount_system);
371
Ethan Yonkerd5801c52014-04-14 08:59:35 -0500372#ifndef TW_OEM_BUILD
Dees_Troy32c8eb82012-09-11 15:28:06 -0400373 DataManager::GetValue(TW_SIGNED_ZIP_VERIFY_VAR, zip_verify);
Ethan Yonkerd5801c52014-04-14 08:59:35 -0500374#endif
Dees_Troy2673cec2013-04-02 20:22:16 +0000375 DataManager::SetProgress(0);
Ethan Yonkerf96087e2014-11-07 10:38:51 -0600376
bigbiff1f9e4842020-10-31 11:33:15 -0400377 auto package = Package::CreateMemoryPackage(path);
378 if (!package) {
379 return INSTALL_CORRUPT;
that50640482015-08-30 12:08:05 +0200380 }
Ethan Yonkerf96087e2014-11-07 10:38:51 -0600381
Dees_Troy32c8eb82012-09-11 15:28:06 -0400382 if (zip_verify) {
Ethan Yonker74db1572015-10-28 12:44:49 -0500383 gui_msg("verify_zip_sig=Verifying zip signature...");
bigbiff1f9e4842020-10-31 11:33:15 -0400384 static constexpr const char* CERTIFICATE_ZIP_FILE = "/system/etc/security/otacerts.zip";
385 std::vector<Certificate> loaded_keys = LoadKeysFromZipfile(CERTIFICATE_ZIP_FILE);
386 if (loaded_keys.empty()) {
387 LOGERR("Failed to load keys\n");
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500388 return -1;
389 }
bigbiff1f9e4842020-10-31 11:33:15 -0400390 LOGINFO("%zu key(s) loaded from %s\n", loaded_keys.size(), CERTIFICATE_ZIP_FILE);
391
392 ret_val = verify_file(package.get(), loaded_keys, std::bind(&DataManager::SetProgress, std::placeholders::_1));
Dees_Troy2673cec2013-04-02 20:22:16 +0000393 if (ret_val != VERIFY_SUCCESS) {
Ethan Yonker74db1572015-10-28 12:44:49 -0500394 LOGINFO("Zip signature verification failed: %i\n", ret_val);
395 gui_err("verify_zip_fail=Zip signature verification failed!");
Ethan Yonkerecbd3e82017-12-14 14:43:59 -0600396#ifdef USE_MINZIP
Ethan Yonkerf9796a42014-11-08 07:28:03 -0600397 sysReleaseMap(&map);
Ethan Yonkerecbd3e82017-12-14 14:43:59 -0600398#endif
Dees_Troy32c8eb82012-09-11 15:28:06 -0400399 return -1;
Ethan Yonker738be7a2014-12-10 11:40:43 -0600400 } else {
Ethan Yonker74db1572015-10-28 12:44:49 -0500401 gui_msg("verify_zip_done=Zip signature verified successfully.");
Dees_Troy32c8eb82012-09-11 15:28:06 -0400402 }
403 }
bigbiff1f9e4842020-10-31 11:33:15 -0400404
405 ZipArchiveHandle Zip = package->GetZipArchiveHandle();
406 if (!Zip) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000407 return INSTALL_CORRUPT;
408 }
Ethan Yonker941a8992016-12-05 09:04:30 -0600409
Chaosmasterff4f9582020-01-26 15:38:11 +0100410 if (unmount_system) {
411 gui_msg("unmount_system=Unmounting System...");
412 if(!PartitionManager.UnMount_By_Path(PartitionManager.Get_Android_Root_Path(), true)) {
413 gui_err("unmount_system_err=Failed unmounting System");
414 return -1;
415 }
Chaosmaster4ee7cbd2020-06-05 17:38:08 +0200416 unlink("/system");
417 mkdir("/system", 0755);
Chaosmasterff4f9582020-01-26 15:38:11 +0100418 }
419
Ethan Yonker072c8d82016-08-26 22:22:24 -0500420 time_t start, stop;
421 time(&start);
bigbiff1f9e4842020-10-31 11:33:15 -0400422
423 ZipString update_binary_name(UPDATE_BINARY_NAME);
424 ZipEntry update_binary_entry;
425 if (FindEntry(Zip, update_binary_name, &update_binary_entry) == 0) {
Ethan Yonker941a8992016-12-05 09:04:30 -0600426 LOGINFO("Update binary zip\n");
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500427 // Additionally verify the compatibility of the package.
bigbiff1f9e4842020-10-31 11:33:15 -0400428 if (!verify_package_compatibility(Zip)) {
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500429 gui_err("zip_compatible_err=Zip Treble compatibility error!");
bigbiff1f9e4842020-10-31 11:33:15 -0400430 CloseArchive(Zip);
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500431 ret_val = INSTALL_CORRUPT;
432 } else {
bigbiff1f9e4842020-10-31 11:33:15 -0400433 ret_val = Prepare_Update_Binary(Zip);
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500434 if (ret_val == INSTALL_SUCCESS)
bigbiff1f9e4842020-10-31 11:33:15 -0400435 ret_val = Run_Update_Binary(path, wipe_cache, UPDATE_BINARY_ZIP_TYPE);
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500436 }
Ethan Yonker941a8992016-12-05 09:04:30 -0600437 } else {
bigbiff1f9e4842020-10-31 11:33:15 -0400438 ZipString ab_binary_name(AB_OTA);
439 ZipEntry ab_binary_entry;
440 if (FindEntry(Zip, ab_binary_name, &ab_binary_entry) == 0) {
Ethan Yonker941a8992016-12-05 09:04:30 -0600441 LOGINFO("AB zip\n");
Chaosmastera6da6562020-02-07 19:58:10 +0100442 gui_msg(Msg(msg::kHighlight, "flash_ab_inactive=Flashing A/B zip to inactive slot: {1}")(PartitionManager.Get_Active_Slot_Display()=="A"?"B":"A"));
Chaosmaster6c1477d2020-02-03 15:54:32 +0100443 // We need this so backuptool can do its magic
444 bool system_mount_state = PartitionManager.Is_Mounted_By_Path(PartitionManager.Get_Android_Root_Path());
445 bool vendor_mount_state = PartitionManager.Is_Mounted_By_Path("/vendor");
446 PartitionManager.Mount_By_Path(PartitionManager.Get_Android_Root_Path(), true);
447 PartitionManager.Mount_By_Path("/vendor", true);
bigbiff1f9e4842020-10-31 11:33:15 -0400448 TWFunc::copy_file("/system/bin/sh", "/tmp/sh", 0755);
Chaosmaster6c1477d2020-02-03 15:54:32 +0100449 mount("/tmp/sh", "/system/bin/sh", "auto", MS_BIND, NULL);
bigbiff1f9e4842020-10-31 11:33:15 -0400450 ret_val = Run_Update_Binary(path, wipe_cache, AB_OTA_ZIP_TYPE);
Chaosmaster6c1477d2020-02-03 15:54:32 +0100451 umount("/system/bin/sh");
452 unlink("/tmp/sh");
453 if (!vendor_mount_state)
454 PartitionManager.UnMount_By_Path("/vendor", true);
455 if (!system_mount_state)
456 PartitionManager.UnMount_By_Path(PartitionManager.Get_Android_Root_Path(), true);
Chaosmastera6da6562020-02-07 19:58:10 +0100457 gui_warn("flash_ab_reboot=To flash additional zips, please reboot recovery to switch to the updated slot.");
Ethan Yonker941a8992016-12-05 09:04:30 -0600458 } else {
bigbiff1f9e4842020-10-31 11:33:15 -0400459 ZipString binary_name("ui.xml");
460 ZipEntry binary_entry;
461 if (FindEntry(Zip, binary_name, &binary_entry) != 0) {
Ethan Yonker941a8992016-12-05 09:04:30 -0600462 LOGINFO("TWRP theme zip\n");
bigbiff1f9e4842020-10-31 11:33:15 -0400463 ret_val = Install_Theme(path, Zip);
Ethan Yonker941a8992016-12-05 09:04:30 -0600464 } else {
bigbiff1f9e4842020-10-31 11:33:15 -0400465 CloseArchive(Zip);
Ethan Yonker941a8992016-12-05 09:04:30 -0600466 ret_val = INSTALL_CORRUPT;
467 }
468 }
469 }
Ethan Yonker072c8d82016-08-26 22:22:24 -0500470 time(&stop);
471 int total_time = (int) difftime(stop, start);
Ethan Yonker20eb0bc2016-03-22 14:23:28 -0500472 if (ret_val == INSTALL_CORRUPT) {
Ethan Yonker941a8992016-12-05 09:04:30 -0600473 gui_err("invalid_zip_format=Invalid zip file format!");
Ethan Yonker072c8d82016-08-26 22:22:24 -0500474 } else {
475 LOGINFO("Install took %i second(s).\n", total_time);
Ethan Yonker20eb0bc2016-03-22 14:23:28 -0500476 }
Ethan Yonkerf9796a42014-11-08 07:28:03 -0600477 return ret_val;
Dees_Troy32c8eb82012-09-11 15:28:06 -0400478}