blob: 078cd5fa8e38b34583ba2b9359c3ef30b7537576 [file] [log] [blame]
nkk7171c6c502017-01-05 23:55:05 +02001/*
2 Copyright 2017 TeamWin
3 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*/
18
nkk7171c6c502017-01-05 23:55:05 +020019#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23#include <errno.h>
nkk717d1222a2017-11-06 17:27:21 +020024#include <fcntl.h>
25#include <sys/mount.h>
nkk7171c6c502017-01-05 23:55:05 +020026#include <sys/time.h>
nkk717d1222a2017-11-06 17:27:21 +020027#include <dirent.h>
28#include <fnmatch.h>
nkk7171c6c502017-01-05 23:55:05 +020029
nkk7171c6c502017-01-05 23:55:05 +020030#include <signal.h>
31#include <sys/types.h>
32#include <sys/wait.h>
nkk7171c6c502017-01-05 23:55:05 +020033
nkk717d1222a2017-11-06 17:27:21 +020034#include <fstream>
nkk7171c6c502017-01-05 23:55:05 +020035#include <string>
36#include <vector>
37#include <sstream>
38
nkk717d1222a2017-11-06 17:27:21 +020039#ifdef _USING_SHORT_SERVICE_NAMES
40#include <map>
41#endif
42
nkk7171c6c502017-01-05 23:55:05 +020043#include "../../partitions.hpp"
44#include "../../twrp-functions.hpp"
nkk7171c6c502017-01-05 23:55:05 +020045
46using namespace std;
47
48extern "C" {
49 #include <cutils/properties.h>
50}
51
nkk717d1222a2017-11-06 17:27:21 +020052#include "vold_decrypt.h"
53
54namespace {
55
nkk7171c6c502017-01-05 23:55:05 +020056/* Timeouts as defined by ServiceManager */
57
58/* The maximum amount of time to wait for a service to start or stop,
59 * in micro-seconds (really an approximation) */
60#define SLEEP_MAX_USEC 2000000 /* 2 seconds */
61/* The minimal sleeping interval between checking for the service's state
62 * when looping for SLEEP_MAX_USEC */
63#define SLEEP_MIN_USEC 200000 /* 200 msec */
64
65
nkk717d1222a2017-11-06 17:27:21 +020066/* vold response codes defined in ResponseCode.h */
67// 200 series - Requested action has been successfully completed
68#define COMMAND_OKAY 200
69#define PASSWORD_TYPE_RESULT 213
nkk7171c6c502017-01-05 23:55:05 +020070
nkk717d1222a2017-11-06 17:27:21 +020071
72#define LOGINFO(...) do { printf(__VA_ARGS__); if (fp_kmsg) { fprintf(fp_kmsg, "[VOLD_DECRYPT]I:" __VA_ARGS__); fflush(fp_kmsg); } } while (0)
73#define LOGKMSG(...) do { if (fp_kmsg) { fprintf(fp_kmsg, "[VOLD_DECRYPT]K:" __VA_ARGS__); fflush(fp_kmsg); } } while (0)
74#define LOGERROR(...) do { printf(__VA_ARGS__); if (fp_kmsg) { fprintf(fp_kmsg, "[VOLD_DECRYPT]E:" __VA_ARGS__); fflush(fp_kmsg); } } while (0)
nkk7171c6c502017-01-05 23:55:05 +020075
76FILE *fp_kmsg = NULL;
nijel82c821a82018-12-29 04:56:41 -050077int sdkver = 20;
nkk7171c6c502017-01-05 23:55:05 +020078
nkk717d1222a2017-11-06 17:27:21 +020079
80/* Debugging Functions */
nkk7171c6c502017-01-05 23:55:05 +020081#ifdef TW_CRYPTO_SYSTEM_VOLD_DEBUG
nkk7171c6c502017-01-05 23:55:05 +020082
nkk717d1222a2017-11-06 17:27:21 +020083#ifndef VD_STRACE_BIN
84#define VD_STRACE_BIN "/sbin/strace"
85#endif
86
87bool has_strace = false;
88pid_t pid_strace = 0;
89
90void Strace_init_Start(void) {
91 has_strace = TWFunc::Path_Exists(VD_STRACE_BIN);
92 if (!has_strace) {
93 LOGINFO("strace binary (%s) not found, disabling strace in vold_decrypt!\n", VD_STRACE_BIN);
94 return;
95 }
nkk7171c6c502017-01-05 23:55:05 +020096
97 pid_t pid;
98 switch(pid = fork())
99 {
100 case -1:
nkk717d1222a2017-11-06 17:27:21 +0200101 LOGKMSG("forking strace_init failed: %d (%s)!\n", errno, strerror(errno));
102 return;
nkk7171c6c502017-01-05 23:55:05 +0200103 case 0: // child
nkk717d1222a2017-11-06 17:27:21 +0200104 execl(VD_STRACE_BIN, "strace", "-q", "-tt", "-ff", "-v", "-y", "-s", "1000", "-o", "/tmp/strace_init.log", "-p", "1" , NULL);
105 LOGKMSG("strace_init fork failed: %d (%s)!\n", errno, strerror(errno));
nkk7171c6c502017-01-05 23:55:05 +0200106 exit(-1);
107 default:
nkk717d1222a2017-11-06 17:27:21 +0200108 LOGKMSG("Starting strace_init (pid=%d)\n", pid);
109 pid_strace = pid;
110 return;
nkk7171c6c502017-01-05 23:55:05 +0200111 }
112}
nkk717d1222a2017-11-06 17:27:21 +0200113
114void Strace_init_Stop(void) {
115 if (pid_strace > 0) {
116 LOGKMSG("Stopping strace_init (pid=%d)\n", pid_strace);
117 int timeout;
118 int status;
119 pid_t retpid = waitpid(pid_strace, &status, WNOHANG);
120
121 kill(pid_strace, SIGTERM);
122 for (timeout = 5; retpid == 0 && timeout; --timeout) {
123 sleep(1);
124 retpid = waitpid(pid_strace, &status, WNOHANG);
125 }
126 if (retpid)
127 LOGKMSG("strace_init terminated successfully\n");
128 else {
129 // SIGTERM didn't work, kill it instead
130 kill(pid_strace, SIGKILL);
131 for (timeout = 5; retpid == 0 && timeout; --timeout) {
132 sleep(1);
133 retpid = waitpid(pid_strace, &status, WNOHANG);
134 }
135 if (retpid)
136 LOGKMSG("strace_init killed successfully\n");
137 else
138 LOGKMSG("strace_init took too long to kill, may be a zombie process\n");
139 }
140 }
141}
142#endif // TW_CRYPTO_SYSTEM_VOLD_DEBUG
143
nkk7171c6c502017-01-05 23:55:05 +0200144
145/* Convert a binary key of specified length into an ascii hex string equivalent,
146 * without the leading 0x and with null termination
147 *
148 * Original code from cryptfs.c
149 */
nkk717d1222a2017-11-06 17:27:21 +0200150string convert_key_to_hex_ascii(const string& master_key) {
nkk7171c6c502017-01-05 23:55:05 +0200151 size_t i;
152 unsigned char nibble;
153 string master_key_ascii = "";
154
155 for (i = 0; i < master_key.size(); ++i) {
156 nibble = (master_key[i] >> 4) & 0xf;
157 nibble += nibble > 9 ? 0x57 : 0x30;
158 master_key_ascii += nibble;
159
160 nibble = master_key[i] & 0xf;
161 nibble += nibble > 9 ? 0x57 : 0x30;
162 master_key_ascii += nibble;
163 }
164
165 return master_key_ascii;
166}
167
nkk717d1222a2017-11-06 17:27:21 +0200168/* Helper Functions */
169#define PATH_EXISTS(path) (access(path, F_OK) >= 0)
170
171int vrename(const string& oldname, const string& newname, bool verbose = false) {
172 const char *old_name = oldname.c_str();
173 const char *new_name = newname.c_str();
174
175 if (!PATH_EXISTS(old_name))
176 return 0;
177
178 if (rename(old_name, new_name) < 0) {
179 LOGERROR("Moving %s to %s failed: %d (%s)\n", old_name, new_name, errno, strerror(errno));
180 return -1;
181 } else if (verbose)
182 LOGINFO("Renamed %s to %s\n", old_name, new_name);
183 else
184 LOGKMSG("Renamed %s to %s\n", old_name, new_name);
185 return 0;
186}
187
188int vsymlink(const string& oldname, const string& newname, bool verbose = false) {
189 const char *old_name = oldname.c_str();
190 const char *new_name = newname.c_str();
191
192 if (!PATH_EXISTS(old_name))
193 return 0;
194
195 if (symlink(old_name, new_name) < 0) {
196 LOGERROR("Symlink %s -> %s failed: %d (%s)\n", new_name, old_name, errno, strerror(errno));
197 return -1;
198 } else if (verbose)
199 LOGINFO("Symlinked %s -> %s\n", new_name, old_name);
200 else
201 LOGKMSG("Symlinked %s -> %s\n", new_name, old_name);
202 return 0;
203}
204
205
206/* Properties and Services Functions */
207string Wait_For_Property(const string& property_name, int utimeout = SLEEP_MAX_USEC, const string& expected_value = "not_empty") {
nkk7171c6c502017-01-05 23:55:05 +0200208 char prop_value[PROPERTY_VALUE_MAX];
209
210 if (expected_value == "not_empty") {
211 while (utimeout > 0) {
212 property_get(property_name.c_str(), prop_value, "error");
213 if (strcmp(prop_value, "error") != 0)
214 break;
nkk717d1222a2017-11-06 17:27:21 +0200215 LOGKMSG("waiting for %s to get set\n", property_name.c_str());
nkk7171c6c502017-01-05 23:55:05 +0200216 utimeout -= SLEEP_MIN_USEC;
217 usleep(SLEEP_MIN_USEC);;
218 }
219 }
220 else {
221 while (utimeout > 0) {
222 property_get(property_name.c_str(), prop_value, "error");
223 if (strcmp(prop_value, expected_value.c_str()) == 0)
224 break;
nkk717d1222a2017-11-06 17:27:21 +0200225 LOGKMSG("waiting for %s to change from '%s' to '%s'\n", property_name.c_str(), prop_value, expected_value.c_str());
nkk7171c6c502017-01-05 23:55:05 +0200226 utimeout -= SLEEP_MIN_USEC;
nijel82c821a82018-12-29 04:56:41 -0500227 usleep(SLEEP_MIN_USEC);
nkk7171c6c502017-01-05 23:55:05 +0200228 }
229 }
230 property_get(property_name.c_str(), prop_value, "error");
231
232 return prop_value;
233}
234
nkk717d1222a2017-11-06 17:27:21 +0200235string Get_Service_State(const string& initrc_svc) {
nkk7171c6c502017-01-05 23:55:05 +0200236 char prop_value[PROPERTY_VALUE_MAX];
237 string init_svc = "init.svc." + initrc_svc;
238 property_get(init_svc.c_str(), prop_value, "error");
nkk717d1222a2017-11-06 17:27:21 +0200239 return prop_value;
nkk7171c6c502017-01-05 23:55:05 +0200240}
241
nkk717d1222a2017-11-06 17:27:21 +0200242bool Service_Exists(const string& initrc_svc) {
243 return (Get_Service_State(initrc_svc) != "error");
nkk7171c6c502017-01-05 23:55:05 +0200244}
245
nkk717d1222a2017-11-06 17:27:21 +0200246bool Is_Service_Running(const string& initrc_svc) {
247 return (Get_Service_State(initrc_svc) == "running");
nkk7171c6c502017-01-05 23:55:05 +0200248}
249
nkk717d1222a2017-11-06 17:27:21 +0200250bool Is_Service_Stopped(const string& initrc_svc) {
251 return (Get_Service_State(initrc_svc) == "stopped");
252}
253
254bool Start_Service(const string& initrc_svc, int utimeout = SLEEP_MAX_USEC) {
nkk7171c6c502017-01-05 23:55:05 +0200255 string res = "error";
256 string init_svc = "init.svc." + initrc_svc;
257
258 property_set("ctl.start", initrc_svc.c_str());
259
nkk717d1222a2017-11-06 17:27:21 +0200260 res = Wait_For_Property(init_svc, utimeout, "running");
nkk7171c6c502017-01-05 23:55:05 +0200261
nkk717d1222a2017-11-06 17:27:21 +0200262 LOGINFO("Start service %s: %s.\n", initrc_svc.c_str(), res.c_str());
nkk7171c6c502017-01-05 23:55:05 +0200263
264 return (res == "running");
265}
266
nkk717d1222a2017-11-06 17:27:21 +0200267bool Stop_Service(const string& initrc_svc, int utimeout = SLEEP_MAX_USEC) {
nkk7171c6c502017-01-05 23:55:05 +0200268 string res = "error";
269
270 if (Service_Exists(initrc_svc)) {
271 string init_svc = "init.svc." + initrc_svc;
272 property_set("ctl.stop", initrc_svc.c_str());
nkk717d1222a2017-11-06 17:27:21 +0200273 res = Wait_For_Property(init_svc, utimeout, "stopped");
274 LOGINFO("Stop service %s: %s.\n", initrc_svc.c_str(), res.c_str());
nkk7171c6c502017-01-05 23:55:05 +0200275 }
276
277 return (res == "stopped");
278}
279
nkk717d1222a2017-11-06 17:27:21 +0200280
281/* Vendor, Firmware and fstab symlink Functions */
282bool is_Vendor_Mounted(void) {
283 static int is_mounted = -1;
284 if (is_mounted < 0)
285 is_mounted = PartitionManager.Is_Mounted_By_Path("/vendor") ? 1 : 0;
286 return is_mounted;
nkk7171c6c502017-01-05 23:55:05 +0200287}
288
nkk717d1222a2017-11-06 17:27:21 +0200289bool is_Firmware_Mounted(void) {
290 static int is_mounted = -1;
291 if (is_mounted < 0)
292 is_mounted = PartitionManager.Is_Mounted_By_Path("/firmware") ? 1 : 0;
293 return is_mounted;
294}
295
296bool will_VendorBin_Be_Symlinked(void) {
297 return (!is_Vendor_Mounted() && TWFunc::Path_Exists("/system/vendor"));
298}
299
300bool Symlink_Vendor_Folder(void) {
301 bool is_vendor_symlinked = false;
302
303 if (is_Vendor_Mounted()) {
304 LOGINFO("vendor partition mounted, skipping /vendor substitution\n");
305 }
306 else if (TWFunc::Path_Exists("/system/vendor")) {
307 LOGINFO("Symlinking vendor folder...\n");
308 if (!TWFunc::Path_Exists("/vendor") || vrename("/vendor", "/vendor-orig") == 0) {
309 TWFunc::Recursive_Mkdir("/vendor/firmware/keymaster");
nkk7137625a42017-12-08 16:37:59 +0200310 vsymlink("/system/vendor/lib64", "/vendor/lib64", true);
311 vsymlink("/system/vendor/lib", "/vendor/lib", true);
312 vsymlink("/system/vendor/bin", "/vendor/bin", true);
nkk717d1222a2017-11-06 17:27:21 +0200313 is_vendor_symlinked = true;
314 property_set("vold_decrypt.symlinked_vendor", "1");
315 }
316 }
317 return is_vendor_symlinked;
318}
319
320void Restore_Vendor_Folder(void) {
321 property_set("vold_decrypt.symlinked_vendor", "0");
322 TWFunc::removeDir("/vendor", false);
323 vrename("/vendor-orig", "/vendor");
324}
325
326bool Symlink_Firmware_Folder(void) {
327 bool is_firmware_symlinked = false;
328
329 if (is_Firmware_Mounted()) {
330 LOGINFO("firmware partition mounted, skipping /firmware substitution\n");
331 }
332 else {
333 LOGINFO("Symlinking firmware folder...\n");
334 if (!TWFunc::Path_Exists("/firmware") || vrename("/firmware", "/firmware-orig") == 0) {
335 TWFunc::Recursive_Mkdir("/firmware/image");
336 is_firmware_symlinked = true;
337 property_set("vold_decrypt.symlinked_firmware", "1");
338 }
339 }
340 return is_firmware_symlinked;
341}
342
343void Restore_Firmware_Folder(void) {
344 property_set("vold_decrypt.symlinked_firmware", "0");
345 TWFunc::removeDir("/firmware", false);
346 vrename("/firmware-orig", "/firmware");
347}
348
349int Find_Firmware_Files(const string& Path, vector<string> *FileList) {
350 int ret;
351 DIR* d;
352 struct dirent* de;
353 string FileName;
354
355 d = opendir(Path.c_str());
356 if (d == NULL) {
357 closedir(d);
358 return -1;
359 }
360 while ((de = readdir(d)) != NULL) {
361 if (de->d_type == DT_DIR) {
362 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
363 continue;
364 FileName = Path + "/" + de->d_name;
365 ret = Find_Firmware_Files(FileName, FileList);
366 if (ret < 0)
367 return -1;
368 } else if (de->d_type == DT_REG) {
369 if (fnmatch("keymaste*.*", de->d_name, 0) == 0 || fnmatch("cmnlib.*", de->d_name, 0) == 0) {
370 FileName = Path + "/" + de->d_name;
371 FileList->push_back(FileName);
372 }
373 }
374 }
375 closedir(d);
376 return 0;
377}
378
379void Symlink_Firmware_Files(bool is_vendor_symlinked, bool is_firmware_symlinked) {
380 if (!is_vendor_symlinked && !is_firmware_symlinked)
381 return;
382
383 LOGINFO("Symlinking firmware files...\n");
384
385 vector<string> FirmwareFiles;
386 Find_Firmware_Files("/system", &FirmwareFiles);
387
388 for (size_t i = 0; i < FirmwareFiles.size(); ++i) {
389 string base_name = TWFunc::Get_Filename(FirmwareFiles[i]);
390
391 if (is_firmware_symlinked)
392 vsymlink(FirmwareFiles[i], "/firmware/image/" + base_name);
393
394 if (is_vendor_symlinked) {
395 vsymlink(FirmwareFiles[i], "/vendor/firmware/" + base_name);
396 vsymlink(FirmwareFiles[i], "/vendor/firmware/keymaster/" + base_name);
397 }
398 }
399 LOGINFO("%d file(s) symlinked.\n", (int)FirmwareFiles.size());
400}
401
402// Android 8.0 fs_mgr checks for "/sbin/recovery", in which case it will
403// use /etc/recovery.fstab -> symlink it temporarily. Reference:
404// https://android.googlesource.com/platform/system/core/+/android-8.0.0_r17/fs_mgr/fs_mgr_fstab.cpp#693
405bool Symlink_Recovery_Fstab(void) {
406 bool is_fstab_symlinked = false;
407
408 if (vrename("/etc/recovery.fstab", "/etc/recovery-fstab-orig") == 0) {
409 is_fstab_symlinked = true;
410
411 // now attempt to symlink to /fstab.{ro.hardware}, but even if that
412 // fails, keep TWRP's fstab hidden since it cannot be parsed by fs_mgr
413 char prop_value[PROPERTY_VALUE_MAX];
414 property_get("ro.hardware", prop_value, "error");
415 if (strcmp(prop_value, "error")) {
416 string fstab_device = "/fstab."; fstab_device += prop_value;
417 vsymlink(fstab_device, "/etc/recovery.fstab");
418 }
419 }
420 return is_fstab_symlinked;
421}
422
423void Restore_Recovery_Fstab(void) {
424 unlink("/etc/recovery.fstab");
425 vrename("/etc/recovery-fstab-orig", "/etc/recovery.fstab");
426}
427
428
429/* Additional Services Functions */
430#ifdef TW_CRYPTO_SYSTEM_VOLD_SERVICES
431typedef struct {
432 string Service_Name;
433 string Service_Path;
434 string Service_Binary;
435
436 string VOLD_Service_Name;
437 string TWRP_Service_Name;
438 bool is_running;
439 bool resume;
nkk7137625a42017-12-08 16:37:59 +0200440 bool bin_exists;
441 bool svc_exists;
nkk717d1222a2017-11-06 17:27:21 +0200442} AdditionalService;
443
444typedef struct {
445 string Service_Name;
446 string Service_Path;
447 string Service_Binary;
448} RC_Service;
449
450// expand_props() courtesy of platform_system_core_init_util.cpp
451bool expand_props(const std::string& src, std::string* dst) {
452 const char* src_ptr = src.c_str();
453
454 if (!dst) {
455 return false;
456 }
457
458 /* - variables can either be $x.y or ${x.y}, in case they are only part
459 * of the string.
460 * - will accept $$ as a literal $.
461 * - no nested property expansion, i.e. ${foo.${bar}} is not supported,
462 * bad things will happen
463 * - ${x.y:-default} will return default value if property empty.
464 */
465 while (*src_ptr) {
466 const char* c;
467
468 c = strchr(src_ptr, '$');
469 if (!c) {
470 dst->append(src_ptr);
471 return true;
472 }
473
474 dst->append(src_ptr, c);
475 c++;
476
477 if (*c == '$') {
478 dst->push_back(*(c++));
479 src_ptr = c;
480 continue;
481 } else if (*c == '\0') {
482 return true;
483 }
484
485 std::string prop_name;
486 std::string def_val;
487 if (*c == '{') {
488 c++;
489 const char* end = strchr(c, '}');
490 if (!end) {
491 // failed to find closing brace, abort.
492 return false;
493 }
494 prop_name = std::string(c, end);
495 c = end + 1;
496 size_t def = prop_name.find(":-");
497 if (def < prop_name.size()) {
498 def_val = prop_name.substr(def + 2);
499 prop_name = prop_name.substr(0, def);
500 }
501 } else {
502 prop_name = c;
503 c += prop_name.size();
504 }
505
506 if (prop_name.empty()) {
507 return false;
508 }
509
510 char prop_value[PROPERTY_VALUE_MAX];
511 property_get(prop_name.c_str(), prop_value, "");
512 std::string prop_val = prop_value;
513 if (prop_val.empty()) {
514 if (def_val.empty()) {
515 return false;
516 }
517 prop_val = def_val;
518 }
519
520 dst->append(prop_val);
521 src_ptr = c;
522 }
523
524 return true;
525}
526
527string GetArgument(const string& line, size_t argument_number, bool expand_properties) {
528 size_t beg;
529 size_t end;
530 string argument;
531
532 beg = line.find_first_not_of(" \t\r");
533 if (beg == string::npos)
534 return "";
535
536 for (size_t i = 0; i < argument_number; ++i) {
537 end = line.find_first_of(" \t\r", beg);
538 if (end == string::npos)
539 return "";
540
541 beg = line.find_first_not_of(" \t\r", end);
542 if (beg == string::npos)
543 return "";
544 }
545
546 end = line.find_first_of(" \t\r", beg);
547 if (end == string::npos)
548 argument = line.substr(beg);
549 else
550 argument = line.substr(beg, end - beg); // exclude trailing whitespace
551
552 if (expand_properties) {
553 string expanded_property_argument;
554 if (expand_props(argument, &expanded_property_argument))
555 return expanded_property_argument;
556 else
557 return "";
558 } else {
559 return argument;
560 }
561}
562
563// Very simplified .rc parser to get services
564void Parse_RC_File(const string& rc_file, vector<RC_Service>& RC_Services) {
565 ifstream file;
566
567 file.open(rc_file.c_str(), ios::in);
568 if (!file.is_open())
569 return;
570
571 size_t beg; // left trim
572 size_t end; // right trim
573 bool continuation = false; // backslash continuation
574 string line; // line
575 string real_line; // trimmed line with backslash continuation removal
576 vector<string> imports; // file names of imports (we don't want to recursively do while the file is open)
577
578 while (getline(file, line)) {
579 beg = line.find_first_not_of(" \t\r");
580 end = line.find_last_not_of(" \t\r");
581 if (end == string::npos)
582 end = line.length();
583
584 if (beg == string::npos) {
585 if (continuation)
586 continuation = false;
587 else
588 continue;
589 } else if (line[end] == '\\') {
590 continuation = true;
591 real_line += line.substr(beg, end - beg); // excluding backslash
592 continue;
593 } else if (continuation) {
594 continuation = false;
595 real_line += line.substr(beg, end - beg + 1);
596 } else {
597 real_line = line.substr(beg, end - beg + 1);
598 }
599
600 if (GetArgument(real_line, 0, false) == "import") {
601 // handle: import <file>
602 string file_name = GetArgument(real_line, 1, true);
603 if (file_name.empty()) {
604 // INVALID IMPORT
605 } else
606 imports.push_back(file_name);
607 } else if (GetArgument(real_line, 0, false) == "service") {
608 // handle: service <name> <path>
609 RC_Service svc;
610
611 svc.Service_Name = GetArgument(real_line, 1, false);
612 svc.Service_Path = GetArgument(real_line, 2, true);
613
614 if (svc.Service_Name.empty() || svc.Service_Path.empty()) {
615 // INVALID SERVICE ENTRY
616 } else {
617 beg = svc.Service_Path.find_last_of("/");
618 if (beg == string::npos)
619 svc.Service_Binary = svc.Service_Path;
620 else
621 svc.Service_Binary = svc.Service_Path.substr(beg + 1);
622
623/*
624#ifdef _USING_SHORT_SERVICE_NAMES
625 if (svc.Service_Name.length() > 16) {
626 LOGERROR("WARNING: Ignoring service %s (-> %s)\n"
627 " defined in %s is greater than 16 characters and will\n"
628 " not be able to be run by init on android-7.1 or below!\n",
629 svc.Service_Name.c_str(), svc.Service_Path.c_str(), rc_file.c_str()
630 );
631 }
632 else
633#endif
634*/
635 RC_Services.push_back(svc);
636 }
637 }
638 real_line.clear();
639 }
640 file.close();
641
642 for (size_t i = 0; i < imports.size(); ++i) {
643 Parse_RC_File(imports[i], RC_Services);
644 }
645}
646
647vector<AdditionalService> Get_List_Of_Additional_Services(void) {
648 vector<AdditionalService> services;
649
650 // Additional Services needed by vold_decrypt (eg qseecomd, hwservicemanager, etc)
651 vector<string> service_names = TWFunc::Split_String(TW_CRYPTO_SYSTEM_VOLD_SERVICES, " ");
652 for (size_t i = 0; i < service_names.size(); ++i) {
653 AdditionalService svc;
654 svc.Service_Name = service_names[i];
nkk7137625a42017-12-08 16:37:59 +0200655 svc.bin_exists = false;
656 svc.svc_exists = false;
nkk717d1222a2017-11-06 17:27:21 +0200657 services.push_back(svc);
658
659#ifdef _USING_SHORT_SERVICE_NAMES
660 // Fallback code for >16 character service names which
661 // allows for multiple definitions in custom .rc files
662 if (service_names[i].length() > 12) {
663 svc.Service_Name = service_names[i].substr(0, 12); // 16-4(prefix)=12
nkk7137625a42017-12-08 16:37:59 +0200664 svc.bin_exists = false;
665 svc.svc_exists = false;
nkk717d1222a2017-11-06 17:27:21 +0200666 services.push_back(svc);
667 }
668#endif
669 }
670
671 // Read list of all services defined in all .rc files
672 vector<RC_Service> RC_Services;
673 Parse_RC_File("/init.rc", RC_Services);
674
675
676 // Cross reference Additional Services against the .rc Services and establish
677 // availability of the binaries, otherwise disable it to avoid unnecessary
678 // delays and log spam.
679 // Also check for duplicate entries between TWRP and vold_decrypt so we can
680 // stop and restart any conflicting services.
681 for (size_t i = 0; i < RC_Services.size(); ++i) {
682 string prefix = RC_Services[i].Service_Name.substr(0, 4);
683
684#ifdef _USING_SHORT_SERVICE_NAMES
685 map<string,size_t> rc_indeces;
686#endif
687
688 if (prefix != "sys_" && prefix != "ven_") {
689#ifdef _USING_SHORT_SERVICE_NAMES
690 if (RC_Services[i].Service_Name.length() > 12) {
691 // save this entry for potential binary name match
692 rc_indeces.insert(pair<string,size_t>(RC_Services[i].Service_Binary, i));
693 }
694#endif
695 continue;
696 }
697
698 for (size_t j = 0; j < services.size(); ++j) {
699 string path = RC_Services[i].Service_Path;
700 if (prefix == "ven_" && will_VendorBin_Be_Symlinked()) {
701 path = "/system" + path; // vendor is going to get symlinked to /system/vendor
702 }
703
704 if (RC_Services[i].Service_Name == prefix + services[j].Service_Name) {
nkk7137625a42017-12-08 16:37:59 +0200705 services[j].svc_exists = true;
706
nkk717d1222a2017-11-06 17:27:21 +0200707 if (!services[j].VOLD_Service_Name.empty() && TWFunc::Path_Exists(path)) {
708 // Duplicate match, log but use previous definition
709 LOGERROR("Service %s: VOLD_Service_Name already defined as %s\n", RC_Services[i].Service_Name.c_str(), services[j].VOLD_Service_Name.c_str());
710 }
711 else if (TWFunc::Path_Exists(path)) {
nkk7137625a42017-12-08 16:37:59 +0200712 services[j].bin_exists = true;
nkk717d1222a2017-11-06 17:27:21 +0200713 services[j].VOLD_Service_Name = RC_Services[i].Service_Name; // prefix + service_name
714 services[j].Service_Path = RC_Services[i].Service_Path;
715 services[j].Service_Binary = RC_Services[i].Service_Binary;
716
717 if (Service_Exists(services[j].Service_Name))
718 services[j].TWRP_Service_Name = services[j].Service_Name;
719 else if (Service_Exists("sbin" + services[j].Service_Name))
720 services[j].TWRP_Service_Name = "sbin" + services[j].Service_Name;
721 else
722 services[j].TWRP_Service_Name.clear();
723
724#ifdef _USING_SHORT_SERVICE_NAMES
725 if (services[j].TWRP_Service_Name.empty()) {
726 // Try matching Service_Binary (due to 16 character service_name limit in 7.1 and below)
727 map<string,size_t>::iterator it = rc_indeces.find(services[j].Service_Binary);
728 if (it != rc_indeces.end()) {
729 services[j].TWRP_Service_Name = RC_Services[it->second].Service_Name;
730 }
731 }
732#endif
733 }
734 break;
735 }
736 }
737 }
738
739 LOGINFO("List of additional services for vold_decrypt:\n");
740 for (size_t i = 0; i < services.size(); ++i) {
nkk7137625a42017-12-08 16:37:59 +0200741 if (!services[i].svc_exists) {
742 LOGINFO(" %s: Disabled due to lack of .rc service entry\n", services[i].Service_Name.c_str());
743 } else if (services[i].bin_exists) {
nkk717d1222a2017-11-06 17:27:21 +0200744 if (services[i].TWRP_Service_Name.empty()) {
745 LOGINFO(" %s: Enabled as %s -> %s\n",
746 services[i].Service_Name.c_str(),
747 services[i].VOLD_Service_Name.c_str(), services[i].Service_Path.c_str()
748 );
749 } else {
750 LOGINFO(" %s: Enabled as %s -> %s (temporarily replacing TWRP's %s service)\n",
751 services[i].Service_Name.c_str(),
752 services[i].VOLD_Service_Name.c_str(), services[i].Service_Path.c_str(),
753 services[i].TWRP_Service_Name.c_str()
754 );
755 }
756 }
nkk7137625a42017-12-08 16:37:59 +0200757 else {
nkk717d1222a2017-11-06 17:27:21 +0200758 LOGINFO(" %s: Disabled due to lack of matching binary\n", services[i].Service_Name.c_str());
nkk7137625a42017-12-08 16:37:59 +0200759 }
nkk717d1222a2017-11-06 17:27:21 +0200760 }
761 return services;
762}
763#endif
764
765
766/* Misc Functions */
767void Set_Needed_Properties(void) {
nkk7171c6c502017-01-05 23:55:05 +0200768 // vold won't start without ro.storage_structure on Kitkat
769 string sdkverstr = TWFunc::System_Property_Get("ro.build.version.sdk");
nkk7171c6c502017-01-05 23:55:05 +0200770 if (!sdkverstr.empty()) {
771 sdkver = atoi(sdkverstr.c_str());
772 }
773 if (sdkver <= 19) {
774 string ro_storage_structure = TWFunc::System_Property_Get("ro.storage_structure");
775 if (!ro_storage_structure.empty())
776 property_set("ro.storage_structure", ro_storage_structure.c_str());
777 }
nijel82c821a82018-12-29 04:56:41 -0500778 property_set("hwservicemanager.ready", "false");
779 property_set("sys.listeners.registered", "false");
780 property_set("vendor.sys.listeners.registered", "false");
nkk7171c6c502017-01-05 23:55:05 +0200781}
782
Captain Throwback89a03cc2020-02-04 15:34:06 -0500783void Update_Patch_Level(void) {
784 // On Oreo and above, keymaster requires Android version & patch level to match installed system
785 string sdkverstr = TWFunc::System_Property_Get("ro.build.version.sdk");
786 if (!sdkverstr.empty()) {
787 sdkver = atoi(sdkverstr.c_str());
788 }
789 if (sdkver <= 25) {
790 property_set("vold_decrypt.legacy_system", "true");
791 } else {
792 LOGINFO("Current system is Oreo or above. Setting OS version and security patch level from installed system...\n");
793 property_set("vold_decrypt.legacy_system", "false");
794 }
795
796 char prop_value[PROPERTY_VALUE_MAX];
797 char legacy_system_value[PROPERTY_VALUE_MAX] = "false";
798 property_get("vold_decrypt.legacy_system", prop_value, "");
799
800 // Only set OS ver and patch level if device uses Oreo+ system
801 if (strcmp(prop_value, legacy_system_value) == 0) {
802 property_get("ro.build.version.release", prop_value, "");
803 std::string osver_orig = prop_value;
804 property_set("vold_decrypt.osver_orig", osver_orig.c_str());
805 LOGINFO("Current OS version: %s\n", osver_orig.c_str());
806
807 int error = 0;
808 std::string osver = TWFunc::System_Property_Get("ro.build.version.release");
809 if (!(osver == osver_orig)) {
810 if (!(error = TWFunc::Property_Override("ro.build.version.release", osver))) {
811 LOGINFO("Property override successful! New OS version: %s\n", osver.c_str());
812 } else {
813 LOGERROR("Property override failed, code %d\n", error);
814 return;
815 }
816 // TODO: Confirm whether we actually need to update the props in prop.default
817 std::string sed_osver = "sed -i 's/ro.build.version.release=.*/ro.build.version.release=" + osver + "/g' /prop.default";
818 TWFunc::Exec_Cmd(sed_osver);
819 property_set("vold_decrypt.osver_set", "true");
820 } else {
821 LOGINFO("Current OS version & System OS version already match. Proceeding to next step.\n");
822 property_set("vold_decrypt.osver_set", "false");
823 }
824
825 property_get("ro.build.version.security_patch", prop_value, "");
826 std::string patchlevel_orig = prop_value;
827 property_set("vold_decrypt.patchlevel_orig", patchlevel_orig.c_str());
828 LOGINFO("Current security patch level: %s\n", patchlevel_orig.c_str());
829
830 std::string patchlevel = TWFunc::System_Property_Get("ro.build.version.security_patch");
831 if (!(patchlevel == patchlevel_orig)) {
832 if (!(error = TWFunc::Property_Override("ro.build.version.security_patch", patchlevel))) {
833 LOGINFO("Property override successful! New security patch level: %s\n", patchlevel.c_str());
834 } else {
835 LOGERROR("Property override failed, code %d\n", error);
836 return;
837 }
838 // TODO: Confirm whether we actually need to update the props in prop.default
839 std::string sed_patchlevel = "sed -i 's/ro.build.version.security_patch=.*/ro.build.version.security_patch=" + patchlevel + "/g' /prop.default";
840 TWFunc::Exec_Cmd(sed_patchlevel);
841 property_set("vold_decrypt.patchlevel_set", "true");
842 } else {
843 LOGINFO("Current security patch level & System security patch level already match. Proceeding to next step.\n");
844 property_set("vold_decrypt.patchlevel_set", "false");
845 }
846 return;
847 } else {
848 LOGINFO("Current system is Nougat or older. Skipping OS version and security patch level setting...\n");
849 return;
850 }
851}
852
853void Revert_Patch_Level(void) {
854 char osver_set[PROPERTY_VALUE_MAX];
855 char patchlevel_set[PROPERTY_VALUE_MAX];
856 char osver_patchlevel_set[PROPERTY_VALUE_MAX] = "false";
857
858 property_get("vold_decrypt.osver_set", osver_set, "");
859 property_get("vold_decrypt.patchlevel_set", patchlevel_set, "");
860
861 int osver_result = strcmp(osver_set, osver_patchlevel_set);
862 int patchlevel_result = strcmp(patchlevel_set, osver_patchlevel_set);
863 if (!(osver_result == 0 && patchlevel_result == 0)) {
864 char prop_value[PROPERTY_VALUE_MAX];
865 LOGINFO("Reverting OS version and security patch level to original TWRP values...\n");
866 property_get("vold_decrypt.osver_orig", prop_value, "");
867 std::string osver_orig = prop_value;
868 property_get("ro.build.version.release", prop_value, "");
869 std::string osver = prop_value;
870
871 int error = 0;
872 if (!(osver == osver_orig)) {
873 if (!(error = TWFunc::Property_Override("ro.build.version.release", osver_orig))) {
874 LOGINFO("Property override successful! Original OS version: %s\n", osver_orig.c_str());
875 } else {
876 LOGERROR("Property override failed, code %d\n", error);
877 return;
878 }
879 // TODO: Confirm whether we actually need to update the props in prop.default
880 std::string sed_osver_orig = "sed -i 's/ro.build.version.release=.*/ro.build.version.release=" + osver_orig + "/g' /prop.default";
881 TWFunc::Exec_Cmd(sed_osver_orig);
882 }
883
884 property_get("vold_decrypt.patchlevel_orig", prop_value, "");
885 std::string patchlevel_orig = prop_value;
886 property_get("ro.build.version.security_patch", prop_value, "");
887 std::string patchlevel = prop_value;
888
889 if (!(patchlevel == patchlevel_orig)) {
890 if (!(error = TWFunc::Property_Override("ro.build.version.security_patch", patchlevel_orig))) {
891 LOGINFO("Property override successful! Original security patch level: %s\n", patchlevel_orig.c_str());
892 } else {
893 LOGERROR("Property override failed, code %d\n", error);
894 return;
895 }
896 // TODO: Confirm whether we actually need to update the props in prop.default
897 std::string sed_patchlevel_orig = "sed -i 's/ro.build.version.security_patch=.*/ro.build.version.security_patch=" + patchlevel_orig + "/g' /prop.default";
898 TWFunc::Exec_Cmd(sed_patchlevel_orig);
899 }
900 } else {
901 return;
902 }
903}
904
nijel82c821a82018-12-29 04:56:41 -0500905static unsigned int get_blkdev_size(int fd) {
906 unsigned long nr_sec;
907
908 if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
909 nr_sec = 0;
910 }
911
912 return (unsigned int) nr_sec;
913}
914
915#define CRYPT_FOOTER_OFFSET 0x4000
916static char footer[16 * 1024];
917const char* userdata_path;
918static off64_t offset;
919
920int footer_br(const string& command) {
921 int fd;
922
923 if (command == "backup") {
924 unsigned int nr_sec;
925 TWPartition* userdata = PartitionManager.Find_Partition_By_Path("/data");
926 userdata_path = userdata->Actual_Block_Device.c_str();
927 fd = open(userdata_path, O_RDONLY);
928 if (fd < 0) {
929 LOGERROR("E:footer_backup: Cannot open '%s': %s\n", userdata_path, strerror(errno));
930 return -1;
931 }
932 if ((nr_sec = get_blkdev_size(fd))) {
933 offset = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
934 } else {
935 LOGERROR("E:footer_br: Failed to get offset\n");
936 close(fd);
937 return -1;
938 }
939 if (lseek64(fd, offset, SEEK_SET) == -1) {
940 LOGERROR("E:footer_backup: Failed to lseek64\n");
941 close(fd);
942 return -1;
943 }
944 if (read(fd, footer, sizeof(footer)) != sizeof(footer)) {
945 LOGERROR("E:footer_br: Failed to read: %s\n", strerror(errno));
946 close(fd);
947 return -1;
948 }
949 close(fd);
950 } else if (command == "restore") {
951 fd = open(userdata_path, O_WRONLY);
952 if (fd < 0) {
953 LOGERROR("E:footer_restore: Cannot open '%s': %s\n", userdata_path, strerror(errno));
954 return -1;
955 }
956 if (lseek64(fd, offset, SEEK_SET) == -1) {
957 LOGERROR("E:footer_restore: Failed to lseek64\n");
958 close(fd);
959 return -1;
960 }
961 if (write(fd, footer, sizeof(footer)) != sizeof(footer)) {
962 LOGERROR("E:footer_br: Failed to write: %s\n", strerror(errno));
963 close(fd);
964 return -1;
965 }
966 close(fd);
967 } else {
968 LOGERROR("E:footer_br: wrong command argument: %s\n", command.c_str());
969 return -1;
970 }
971 return 0;
972}
nkk7171c6c502017-01-05 23:55:05 +0200973
nkk717d1222a2017-11-06 17:27:21 +0200974/* vdc Functions */
975typedef struct {
976 string Output; // Entire line excluding \n
977 int ResponseCode; // ResponseCode.h (int)
978 int Sequence; // Sequence (int)
979 int Message; // Message (string) but we're only interested in int
980} vdc_ReturnValues;
981
982int Exec_vdc_cryptfs(const string& command, const string& argument, vdc_ReturnValues* vdcResult) {
983 pid_t pid;
984 int status;
nkk7137625a42017-12-08 16:37:59 +0200985 int pipe_fd[2][2];
nkk717d1222a2017-11-06 17:27:21 +0200986
nkk7137625a42017-12-08 16:37:59 +0200987 vdcResult->Output.clear();
988 vdcResult->ResponseCode = vdcResult->Sequence = vdcResult->Message = -1;
989
990 for (int i = 0; i < 2; ++i) {
991 if (pipe(pipe_fd[i])) {
992 LOGERROR("exec_vdc_cryptfs: pipe() error!\n");
993 return -1;
994 }
nkk717d1222a2017-11-06 17:27:21 +0200995 }
996
nijel82c821a82018-12-29 04:56:41 -0500997 // getpwtype and checkpw commands are removed from Pie vdc, using modified vdc_pie
998 const char *cmd[] = { "/sbin/vdc_pie", "cryptfs" };
999 if (sdkver < 28)
1000 cmd[0] = "/system/bin/vdc";
nkk717d1222a2017-11-06 17:27:21 +02001001 const char *env[] = { "LD_LIBRARY_PATH=/system/lib64:/system/lib", NULL };
1002
nijel82c821a82018-12-29 04:56:41 -05001003 LOGINFO("sdkver: %d, using %s\n", sdkver, cmd[0]);
1004
nkk717d1222a2017-11-06 17:27:21 +02001005#ifdef TW_CRYPTO_SYSTEM_VOLD_DEBUG
1006 string log_name = "/tmp/strace_vdc_" + command;
nkk7171c6c502017-01-05 23:55:05 +02001007#endif
nkk7171c6c502017-01-05 23:55:05 +02001008
nkk717d1222a2017-11-06 17:27:21 +02001009 switch(pid = fork())
1010 {
1011 case -1:
1012 LOGERROR("exec_vdc_cryptfs: fork failed: %d (%s)!\n", errno, strerror(errno));
1013 return -1;
1014
1015 case 0: // child
1016 fflush(stdout); fflush(stderr);
nkk7137625a42017-12-08 16:37:59 +02001017 for (int i = 0; i < 2; ++i) {
1018 close(pipe_fd[i][0]);
1019 dup2(pipe_fd[i][1], ((i == 0) ? STDOUT_FILENO : STDERR_FILENO));
1020 close(pipe_fd[i][1]);
1021 }
nkk717d1222a2017-11-06 17:27:21 +02001022
1023#ifdef TW_CRYPTO_SYSTEM_VOLD_DEBUG
1024 if (has_strace) {
1025 if (argument.empty())
1026 execl(VD_STRACE_BIN, "strace", "-q", "-tt", "-ff", "-v", "-y", "-s", "1000", "-o", log_name.c_str(),
1027 "-E", env[0], cmd[0], cmd[1], command.c_str(), NULL);
1028 else
1029 execl(VD_STRACE_BIN, "strace", "-q", "-tt", "-ff", "-v", "-y", "-s", "1000", "-o", log_name.c_str(),
1030 "-E", env[0], cmd[0], cmd[1], command.c_str(), argument.c_str(), NULL);
1031 } else
1032#endif
1033 if (argument.empty())
1034 execle(cmd[0], cmd[0], cmd[1], command.c_str(), NULL, env);
1035 else
1036 execle(cmd[0], cmd[0], cmd[1], command.c_str(), argument.c_str(), NULL, env);
1037 _exit(127);
1038 break;
1039
1040 default:
1041 {
1042 int timeout = 30*100;
nkk717d1222a2017-11-06 17:27:21 +02001043
nkk7137625a42017-12-08 16:37:59 +02001044 for (int i = 0; i < 2; ++i) {
1045 close(pipe_fd[i][1]);
1046
1047 // Non-blocking read loop with timeout
1048 int flags = fcntl(pipe_fd[i][0], F_GETFL, 0);
1049 fcntl(pipe_fd[i][0], F_SETFL, flags | O_NONBLOCK);
1050 }
nkk717d1222a2017-11-06 17:27:21 +02001051
1052 char buffer[128];
1053 ssize_t count;
nkk7137625a42017-12-08 16:37:59 +02001054 string strout[2];
nkk717d1222a2017-11-06 17:27:21 +02001055 pid_t retpid = waitpid(pid, &status, WNOHANG);
1056 while (true) {
nkk7137625a42017-12-08 16:37:59 +02001057 for (int i = 0; i < 2; ++i) {
1058 count = read(pipe_fd[i][0], buffer, sizeof(buffer));
1059 if (count == -1) {
1060 if (errno == EINTR)
1061 continue;
1062 else if (errno != EAGAIN)
1063 LOGERROR("exec_vdc_cryptfs: read() error %d (%s)\n!", errno, strerror(errno));
1064 } else if (count > 0) {
1065 strout[i].append(buffer, count);
1066 }
nkk717d1222a2017-11-06 17:27:21 +02001067 }
1068
1069 retpid = waitpid(pid, &status, WNOHANG);
1070 if (retpid == 0 && --timeout)
1071 usleep(10000);
1072 else
1073 break;
1074 };
nkk7137625a42017-12-08 16:37:59 +02001075
1076 for (int i = 0; i < 2; ++i) {
1077 close(pipe_fd[i][0]);
1078 }
1079
1080 if (!strout[0].empty()) {
1081 sscanf(strout[0].c_str(), "%d %d %d", &vdcResult->ResponseCode, &vdcResult->Sequence, &vdcResult->Message);
1082 vdcResult->Output = "I:" + strout[0];
1083 }
1084 if (!strout[1].empty()) {
1085 vdcResult->Output += "E:" + strout[1];
1086 }
1087 std::replace(vdcResult->Output.begin(), vdcResult->Output.end(), '\n', '|');
1088
1089 if (!vdcResult->Output.empty() && vdcResult->Output[vdcResult->Output.length() - 1] != '|')
1090 vdcResult->Output += "|";
1091 vdcResult->Output += "RC=" + TWFunc::to_string(WEXITSTATUS(status));
nkk717d1222a2017-11-06 17:27:21 +02001092
1093 // Error handling
1094 if (retpid == 0 && timeout == 0) {
1095 LOGERROR("exec_vdc_cryptfs: took too long, killing process\n");
1096 kill(pid, SIGKILL);
1097 for (timeout = 5; retpid == 0 && timeout; --timeout) {
1098 sleep(1);
1099 retpid = waitpid(pid, &status, WNOHANG);
1100 }
1101 if (retpid)
1102 LOGINFO("exec_vdc_cryptfs: process killed successfully\n");
1103 else
1104 LOGERROR("exec_vdc_cryptfs: process took too long to kill, may be a zombie process\n");
1105 return VD_ERR_VOLD_OPERATION_TIMEDOUT;
1106 } else if (retpid > 0) {
1107 if (WIFSIGNALED(status)) {
1108 LOGERROR("exec_vdc_cryptfs: process ended with signal: %d\n", WTERMSIG(status)); // Seg fault or some other non-graceful termination
1109 return -1;
1110 }
1111 } else if (retpid < 0) { // no PID returned
1112 if (errno == ECHILD)
1113 LOGINFO("exec_vdc_cryptfs: no child process exist\n");
1114 else {
1115 LOGERROR("exec_vdc_cryptfs: Unexpected error %d (%s)\n", errno, strerror(errno));
1116 return -1;
1117 }
1118 }
nijel82c821a82018-12-29 04:56:41 -05001119 if (sdkver >= 28) {
1120 return WEXITSTATUS(status);
1121 }
nkk717d1222a2017-11-06 17:27:21 +02001122 return 0;
1123 }
1124 }
nkk7171c6c502017-01-05 23:55:05 +02001125}
1126
nkk717d1222a2017-11-06 17:27:21 +02001127int Run_vdc(const string& Password) {
1128 int res;
nkk7171c6c502017-01-05 23:55:05 +02001129 struct timeval t1, t2;
nkk717d1222a2017-11-06 17:27:21 +02001130 vdc_ReturnValues vdcResult;
nkk7171c6c502017-01-05 23:55:05 +02001131
nkk717d1222a2017-11-06 17:27:21 +02001132 LOGINFO("About to run vdc...\n");
nkk7171c6c502017-01-05 23:55:05 +02001133
nijel82c821a82018-12-29 04:56:41 -05001134 // Pie vdc communicates with vold directly, no socket so lets not waste time
1135 if (sdkver < 28) {
1136 // Wait for vold connection
1137 gettimeofday(&t1, NULL);
1138 t2 = t1;
1139 while ((t2.tv_sec - t1.tv_sec) < 5) {
1140 // cryptfs getpwtype returns: R1=213(PasswordTypeResult) R2=? R3="password", "pattern", "pin", "default"
1141 res = Exec_vdc_cryptfs("getpwtype", "", &vdcResult);
1142 if (vdcResult.ResponseCode == PASSWORD_TYPE_RESULT) {
1143 res = 0;
1144 break;
1145 }
1146 LOGINFO("Retrying connection to vold (Reason: %s)\n", vdcResult.Output.c_str());
1147 usleep(SLEEP_MIN_USEC); // vdc usually usleep(10000), but that causes too many unnecessary attempts
1148 gettimeofday(&t2, NULL);
nkk7171c6c502017-01-05 23:55:05 +02001149 }
nijel82c821a82018-12-29 04:56:41 -05001150
1151 if (res == 0 && (t2.tv_sec - t1.tv_sec) < 5)
1152 LOGINFO("Connected to vold: %s\n", vdcResult.Output.c_str());
1153 else if (res == VD_ERR_VOLD_OPERATION_TIMEDOUT)
1154 return VD_ERR_VOLD_OPERATION_TIMEDOUT; // should never happen for getpwtype
1155 else if (res)
1156 return VD_ERR_FORK_EXECL_ERROR;
1157 else if (vdcResult.ResponseCode != -1)
1158 return VD_ERR_VOLD_UNEXPECTED_RESPONSE;
1159 else
1160 return VD_ERR_VDC_FAILED_TO_CONNECT;
nkk7171c6c502017-01-05 23:55:05 +02001161 }
1162
nkk7171c6c502017-01-05 23:55:05 +02001163 // Input password from GUI, or default password
nkk717d1222a2017-11-06 17:27:21 +02001164 res = Exec_vdc_cryptfs("checkpw", Password, &vdcResult);
1165 if (res == VD_ERR_VOLD_OPERATION_TIMEDOUT)
1166 return VD_ERR_VOLD_OPERATION_TIMEDOUT;
1167 else if (res)
1168 return VD_ERR_FORK_EXECL_ERROR;
nkk7171c6c502017-01-05 23:55:05 +02001169
nkk7137625a42017-12-08 16:37:59 +02001170 LOGINFO("vdc cryptfs result (passwd): %s\n", vdcResult.Output.c_str());
nkk717d1222a2017-11-06 17:27:21 +02001171 /*
1172 if (res == 0 && vdcResult.ResponseCode != COMMAND_OKAY)
1173 return VD_ERR_VOLD_UNEXPECTED_RESPONSE;
1174 */
1175
nijel82c821a82018-12-29 04:56:41 -05001176 // our vdc returns vold binder op status,
1177 // we care about status.ok() only which is 0
1178 if (sdkver >= 28) {
1179 vdcResult.Message = res;
1180 }
1181
nkk717d1222a2017-11-06 17:27:21 +02001182 if (vdcResult.Message != 0) {
nkk7171c6c502017-01-05 23:55:05 +02001183 // try falling back to Lollipop hex passwords
1184 string hexPassword = convert_key_to_hex_ascii(Password);
nkk717d1222a2017-11-06 17:27:21 +02001185 res = Exec_vdc_cryptfs("checkpw", hexPassword, &vdcResult);
1186 if (res == VD_ERR_VOLD_OPERATION_TIMEDOUT)
1187 return VD_ERR_VOLD_OPERATION_TIMEDOUT;
1188 else if (res)
1189 return VD_ERR_FORK_EXECL_ERROR;
1190
nkk7137625a42017-12-08 16:37:59 +02001191 LOGINFO("vdc cryptfs result (hex_pw): %s\n", vdcResult.Output.c_str());
nkk717d1222a2017-11-06 17:27:21 +02001192 /*
1193 if (res == 0 && vdcResult.ResponseCode != COMMAND_OKAY)
1194 return VD_ERR_VOLD_UNEXPECTED_RESPONSE;
1195 */
nkk7171c6c502017-01-05 23:55:05 +02001196 }
1197
nijel82c821a82018-12-29 04:56:41 -05001198 // sdk < 28 vdc's return value is dependant upon source origin, it will either
nkk717d1222a2017-11-06 17:27:21 +02001199 // return 0 or ResponseCode, so disregard and focus on decryption instead
nijel82c821a82018-12-29 04:56:41 -05001200 // our vdc always returns 0 on success
nkk717d1222a2017-11-06 17:27:21 +02001201 if (vdcResult.Message == 0) {
nkk7171c6c502017-01-05 23:55:05 +02001202 // Decryption successful wait for crypto blk dev
nkk717d1222a2017-11-06 17:27:21 +02001203 Wait_For_Property("ro.crypto.fs_crypto_blkdev");
1204 res = VD_SUCCESS;
1205 } else if (vdcResult.ResponseCode != COMMAND_OKAY) {
1206 res = VD_ERR_VOLD_UNEXPECTED_RESPONSE;
nkk7171c6c502017-01-05 23:55:05 +02001207 } else {
nkk717d1222a2017-11-06 17:27:21 +02001208 res = VD_ERR_DECRYPTION_FAILED;
nkk7171c6c502017-01-05 23:55:05 +02001209 }
1210
1211 return res;
1212}
1213
nkk717d1222a2017-11-06 17:27:21 +02001214int Vold_Decrypt_Core(const string& Password) {
nkk7171c6c502017-01-05 23:55:05 +02001215 int res;
nkk7171c6c502017-01-05 23:55:05 +02001216 bool is_vendor_symlinked = false;
1217 bool is_firmware_symlinked = false;
nkk717d1222a2017-11-06 17:27:21 +02001218 bool is_fstab_symlinked = false;
nkk7171c6c502017-01-05 23:55:05 +02001219 bool is_vold_running = false;
1220
1221 if (Password.empty()) {
nkk717d1222a2017-11-06 17:27:21 +02001222 LOGINFO("vold_decrypt: password is empty!\n");
1223 return VD_ERR_PASSWORD_EMPTY;
nkk7171c6c502017-01-05 23:55:05 +02001224 }
1225
Captain Throwback6ac30af2018-06-21 10:57:12 -04001226 // Mount ANDROID_ROOT and check for vold and vdc
1227 if (!PartitionManager.Mount_By_Path(PartitionManager.Get_Android_Root_Path(), true)) {
nkk717d1222a2017-11-06 17:27:21 +02001228 return VD_ERR_UNABLE_TO_MOUNT_SYSTEM;
Captain Throwback6ac30af2018-06-21 10:57:12 -04001229 } else if ((!TWFunc::Path_Exists("/system/bin/vold")) && (!TWFunc::Path_Exists(PartitionManager.Get_Android_Root_Path() + "/system/bin/vold"))) {
1230 LOGINFO("ERROR: vold not found, aborting.\n");
nkk717d1222a2017-11-06 17:27:21 +02001231 return VD_ERR_MISSING_VOLD;
Captain Throwback6ac30af2018-06-21 10:57:12 -04001232 } else if ((!TWFunc::Path_Exists("/system/bin/vdc")) && (!TWFunc::Path_Exists(PartitionManager.Get_Android_Root_Path() + "/system/bin/vdc"))) {
1233 LOGINFO("ERROR: vdc not found, aborting.\n");
nkk717d1222a2017-11-06 17:27:21 +02001234 return VD_ERR_MISSING_VDC;
nkk7171c6c502017-01-05 23:55:05 +02001235 }
1236
nijel82c821a82018-12-29 04:56:41 -05001237#ifdef TW_CRYPTO_SYSTEM_VOLD_MOUNT
1238 vector<string> partitions = TWFunc::Split_String(TW_CRYPTO_SYSTEM_VOLD_MOUNT, " ");
1239 for (size_t i = 0; i < partitions.size(); ++i) {
1240 string mnt_point = "/" + partitions[i];
1241 if(PartitionManager.Find_Partition_By_Path(mnt_point)) {
1242 if (!PartitionManager.Mount_By_Path(mnt_point, true)) {
1243 LOGERROR("Unable to mount %s\n", mnt_point.c_str());
1244 return VD_ERR_UNABLE_TO_MOUNT_EXTRA;
1245 }
1246 LOGINFO("%s partition mounted\n", partitions[i].c_str());
1247 }
1248 }
1249#endif
1250
nkk7171c6c502017-01-05 23:55:05 +02001251 fp_kmsg = fopen("/dev/kmsg", "a");
1252
nkk717d1222a2017-11-06 17:27:21 +02001253 LOGINFO("TW_CRYPTO_USE_SYSTEM_VOLD := true\n");
nkk7171c6c502017-01-05 23:55:05 +02001254
nkk717d1222a2017-11-06 17:27:21 +02001255 // just cache the result to avoid unneeded duplicates in recovery.log
1256 LOGINFO("Checking existence of vendor and firmware partitions...\n");
1257 is_Vendor_Mounted();
1258 is_Firmware_Mounted();
1259
1260 LOGINFO("Attempting to use system's vold for decryption...\n");
nkk7171c6c502017-01-05 23:55:05 +02001261
1262#ifdef TW_CRYPTO_SYSTEM_VOLD_DEBUG
nkk717d1222a2017-11-06 17:27:21 +02001263 Strace_init_Start();
nkk7171c6c502017-01-05 23:55:05 +02001264#endif
1265
1266#ifdef TW_CRYPTO_SYSTEM_VOLD_SERVICES
1267 vector<AdditionalService> Services = Get_List_Of_Additional_Services();
1268
1269 // Check if TWRP is running any of the services
1270 for (size_t i = 0; i < Services.size(); ++i) {
nkk717d1222a2017-11-06 17:27:21 +02001271 if (!Services[i].TWRP_Service_Name.empty() && !Is_Service_Stopped(Services[i].TWRP_Service_Name)) {
nkk7171c6c502017-01-05 23:55:05 +02001272 Services[i].resume = true;
nkk717d1222a2017-11-06 17:27:21 +02001273 Stop_Service(Services[i].TWRP_Service_Name);
nkk7171c6c502017-01-05 23:55:05 +02001274 } else
1275 Services[i].resume = false;
nkk7171c6c502017-01-05 23:55:05 +02001276 }
1277#endif
1278
nkk717d1222a2017-11-06 17:27:21 +02001279 LOGINFO("Setting up folders and permissions...\n");
1280 is_fstab_symlinked = Symlink_Recovery_Fstab();
nkk7171c6c502017-01-05 23:55:05 +02001281 is_vendor_symlinked = Symlink_Vendor_Folder();
1282 is_firmware_symlinked = Symlink_Firmware_Folder();
1283 Symlink_Firmware_Files(is_vendor_symlinked, is_firmware_symlinked);
1284
nkk717d1222a2017-11-06 17:27:21 +02001285 Set_Needed_Properties();
Captain Throwback89a03cc2020-02-04 15:34:06 -05001286#ifdef TW_INCLUDE_LIBRESETPROP
1287 Update_Patch_Level();
1288#endif
nkk7171c6c502017-01-05 23:55:05 +02001289
1290 // Start services needed for vold decrypt
nkk717d1222a2017-11-06 17:27:21 +02001291 LOGINFO("Starting services...\n");
nkk7171c6c502017-01-05 23:55:05 +02001292#ifdef TW_CRYPTO_SYSTEM_VOLD_SERVICES
1293 for (size_t i = 0; i < Services.size(); ++i) {
nijel82c821a82018-12-29 04:56:41 -05001294 if (Services[i].bin_exists) {
1295 if (Services[i].Service_Binary.find("keymaster") != string::npos) {
1296 Wait_For_Property("hwservicemanager.ready", 500000, "true");
1297 LOGINFO(" hwservicemanager is ready.\n");
1298 }
1299
nkk717d1222a2017-11-06 17:27:21 +02001300 Services[i].is_running = Start_Service(Services[i].VOLD_Service_Name);
nijel82c821a82018-12-29 04:56:41 -05001301
1302 if (Services[i].Service_Binary == "qseecomd") {
1303 if (Wait_For_Property("sys.listeners.registered", 500000, "true") == "true"
1304 || Wait_For_Property("vendor.sys.listeners.registered", 500000, "true") == "true")
1305 LOGINFO(" qseecomd listeners registered.\n");
1306 }
1307 }
nkk7171c6c502017-01-05 23:55:05 +02001308 }
1309#endif
1310 is_vold_running = Start_Service("sys_vold");
1311
1312 if (is_vold_running) {
nkk7171c6c502017-01-05 23:55:05 +02001313#ifdef TW_CRYPTO_SYSTEM_VOLD_SERVICES
1314 for (size_t i = 0; i < Services.size(); ++i) {
nkk7137625a42017-12-08 16:37:59 +02001315 if (Services[i].bin_exists && !Is_Service_Running(Services[i].VOLD_Service_Name) && Services[i].resume) {
nkk7171c6c502017-01-05 23:55:05 +02001316 // if system_service has died restart the twrp_service
nkk717d1222a2017-11-06 17:27:21 +02001317 LOGINFO("%s is not running, resuming %s!\n", Services[i].VOLD_Service_Name.c_str(), Services[i].TWRP_Service_Name.c_str());
1318 Start_Service(Services[i].TWRP_Service_Name);
nkk7171c6c502017-01-05 23:55:05 +02001319 }
1320 }
1321#endif
nijel82c821a82018-12-29 04:56:41 -05001322
1323 /*
1324 * Oreo and Pie vold on some devices alters footer causing
1325 * system to ask for decryption password at next boot although
1326 * password haven't changed so we save footer before and restore it
1327 * after vold operations
1328 */
1329 if (sdkver > 25) {
1330 if (footer_br("backup") == 0) {
1331 LOGINFO("footer_br: crypto footer backed up\n");
1332 res = Run_vdc(Password);
1333 if (footer_br("restore") == 0)
1334 LOGINFO("footer_br: crypto footer restored\n");
1335 else
1336 LOGERROR("footer_br: Failed to restore crypto footer\n");
1337 } else {
1338 LOGERROR("footer_br: Failed to backup crypto footer, \
1339 skipping decrypt to prevent data loss. Reboot recovery to try again...\n");
1340 res = -1;
1341 }
1342 } else {
1343 res = Run_vdc(Password);
1344 }
nkk7171c6c502017-01-05 23:55:05 +02001345
1346 if (res != 0) {
nkk717d1222a2017-11-06 17:27:21 +02001347 LOGINFO("Decryption failed\n");
nkk7171c6c502017-01-05 23:55:05 +02001348 }
1349 } else {
nkk717d1222a2017-11-06 17:27:21 +02001350 LOGINFO("Failed to start vold\n");
1351 res = VD_ERR_VOLD_FAILED_TO_START;
nkk7171c6c502017-01-05 23:55:05 +02001352 }
Captain Throwback89a03cc2020-02-04 15:34:06 -05001353#ifdef TW_INCLUDE_LIBRESETPROP
1354 Revert_Patch_Level();
1355#endif
nkk7171c6c502017-01-05 23:55:05 +02001356 // Stop services needed for vold decrypt so /system can be unmounted
nkk717d1222a2017-11-06 17:27:21 +02001357 LOGINFO("Stopping services...\n");
nkk7171c6c502017-01-05 23:55:05 +02001358 Stop_Service("sys_vold");
1359#ifdef TW_CRYPTO_SYSTEM_VOLD_SERVICES
1360 for (size_t i = 0; i < Services.size(); ++i) {
nkk717d1222a2017-11-06 17:27:21 +02001361 if (!Is_Service_Running(Services[i].VOLD_Service_Name) && Services[i].resume)
1362 Stop_Service(Services[i].TWRP_Service_Name);
nkk7137625a42017-12-08 16:37:59 +02001363 else if (Services[i].bin_exists)
nkk717d1222a2017-11-06 17:27:21 +02001364 Stop_Service(Services[i].VOLD_Service_Name);
nkk7171c6c502017-01-05 23:55:05 +02001365 }
1366#endif
1367
1368 if (is_firmware_symlinked)
1369 Restore_Firmware_Folder();
1370 if (is_vendor_symlinked)
1371 Restore_Vendor_Folder();
nkk717d1222a2017-11-06 17:27:21 +02001372 if (is_fstab_symlinked)
1373 Restore_Recovery_Fstab();
nkk7171c6c502017-01-05 23:55:05 +02001374
Captain Throwback6ac30af2018-06-21 10:57:12 -04001375 if (!PartitionManager.UnMount_By_Path(PartitionManager.Get_Android_Root_Path(), true)) {
1376 // PartitionManager failed to unmount ANDROID_ROOT, this should not happen,
nkk7171c6c502017-01-05 23:55:05 +02001377 // but in case it does, do a lazy unmount
Captain Throwback6ac30af2018-06-21 10:57:12 -04001378 LOGINFO("WARNING: '%s' could not be unmounted normally!\n", PartitionManager.Get_Android_Root_Path().c_str());
1379 umount2(PartitionManager.Get_Android_Root_Path().c_str(), MNT_DETACH);
nkk7171c6c502017-01-05 23:55:05 +02001380 }
1381
nijel82c821a82018-12-29 04:56:41 -05001382#ifdef TW_CRYPTO_SYSTEM_VOLD_MOUNT
1383 for (size_t i = 0; i < partitions.size(); ++i) {
1384 string mnt_point = "/" + partitions[i];
1385 if(PartitionManager.Is_Mounted_By_Path(mnt_point)) {
1386 if (!PartitionManager.UnMount_By_Path(mnt_point, true)) {
1387 LOGINFO("WARNING: %s partition could not be unmounted normally!\n", partitions[i].c_str());
1388 umount2(mnt_point.c_str(), MNT_DETACH);
1389 }
1390 }
1391 }
1392#endif
1393
nkk717d1222a2017-11-06 17:27:21 +02001394 LOGINFO("Finished.\n");
nkk7171c6c502017-01-05 23:55:05 +02001395
1396#ifdef TW_CRYPTO_SYSTEM_VOLD_SERVICES
nijel82c821a82018-12-29 04:56:41 -05001397 Set_Needed_Properties();
nkk7171c6c502017-01-05 23:55:05 +02001398 // Restart previously running services
1399 for (size_t i = 0; i < Services.size(); ++i) {
nijel82c821a82018-12-29 04:56:41 -05001400 if (Services[i].resume) {
1401 if (Services[i].Service_Binary.find("keymaster") != string::npos) {
1402 Wait_For_Property("hwservicemanager.ready", 500000, "true");
1403 LOGINFO(" hwservicemanager is ready.\n");
1404 }
1405
nkk717d1222a2017-11-06 17:27:21 +02001406 Start_Service(Services[i].TWRP_Service_Name);
nijel82c821a82018-12-29 04:56:41 -05001407
1408 if (Services[i].Service_Binary == "qseecomd") {
1409 if (Wait_For_Property("sys.listeners.registered", 500000, "true") == "true"
1410 || Wait_For_Property("vendor.sys.listeners.registered", 500000, "true") == "true")
1411 LOGINFO(" qseecomd listeners registered.\n");
1412 }
1413 }
nkk7171c6c502017-01-05 23:55:05 +02001414 }
1415#endif
1416
1417#ifdef TW_CRYPTO_SYSTEM_VOLD_DEBUG
nkk717d1222a2017-11-06 17:27:21 +02001418 Strace_init_Stop();
nkk7171c6c502017-01-05 23:55:05 +02001419#endif
1420
1421 // Finish up and exit
1422 if (fp_kmsg) {
1423 fflush(fp_kmsg);
1424 fclose(fp_kmsg);
1425 }
1426
nkk7171c6c502017-01-05 23:55:05 +02001427 return res;
1428}
nkk717d1222a2017-11-06 17:27:21 +02001429
1430} // namespace
1431
1432/*
1433 * Common vold Response Codes / Errors:
1434 * 406 (OpFailedStorageNotFound) -> Problem reading or parsing fstab
1435 *
1436 */
1437
1438/* Main function separated from core in case we want to return error info */
1439int vold_decrypt(const string& Password) {
1440 return Vold_Decrypt_Core(Password);
1441}