diff options
author | Yabin Cui | 2016-06-09 16:09:39 -0500 |
---|---|---|
committer | Yabin Cui | 2016-06-20 20:18:02 -0500 |
commit | 6faf0265c9b58db2c15b53f6d29025629d52f882 (patch) | |
tree | fc2e067205a986071615f936e8ff7040e01520f5 /uncrypt | |
parent | dc1393d09bcc09ae246cd46b2248d9401605d0f5 (diff) | |
download | platform-bootable-recovery-6faf0265c9b58db2c15b53f6d29025629d52f882.tar.gz platform-bootable-recovery-6faf0265c9b58db2c15b53f6d29025629d52f882.tar.xz platform-bootable-recovery-6faf0265c9b58db2c15b53f6d29025629d52f882.zip |
Verify wipe package when wiping A/B device in recovery.
To increase the security of wiping A/B devices, let uncrypt write
wipe package in misc partition. Then recovery verifies the wipe
package before wiping the device.
Bug: 29159185
Change-Id: I186691bab1928d3dc036bc5542abd64a81bc2168
Diffstat (limited to 'uncrypt')
-rw-r--r-- | uncrypt/bootloader_message_writer.cpp | 20 | ||||
-rw-r--r-- | uncrypt/include/bootloader_message_writer.h | 1 | ||||
-rw-r--r-- | uncrypt/uncrypt.cpp | 19 |
3 files changed, 37 insertions, 3 deletions
diff --git a/uncrypt/bootloader_message_writer.cpp b/uncrypt/bootloader_message_writer.cpp index 3bb106aa..42df31ef 100644 --- a/uncrypt/bootloader_message_writer.cpp +++ b/uncrypt/bootloader_message_writer.cpp | |||
@@ -58,7 +58,7 @@ static std::string get_misc_blk_device(std::string* err) { | |||
58 | return record->blk_device; | 58 | return record->blk_device; |
59 | } | 59 | } |
60 | 60 | ||
61 | static bool write_bootloader_message(const bootloader_message& boot, std::string* err) { | 61 | static bool write_misc_partition(const void* p, size_t size, size_t misc_offset, std::string* err) { |
62 | std::string misc_blk_device = get_misc_blk_device(err); | 62 | std::string misc_blk_device = get_misc_blk_device(err); |
63 | if (misc_blk_device.empty()) { | 63 | if (misc_blk_device.empty()) { |
64 | return false; | 64 | return false; |
@@ -69,11 +69,18 @@ static bool write_bootloader_message(const bootloader_message& boot, std::string | |||
69 | strerror(errno)); | 69 | strerror(errno)); |
70 | return false; | 70 | return false; |
71 | } | 71 | } |
72 | if (!android::base::WriteFully(fd.get(), &boot, sizeof(boot))) { | 72 | if (lseek(fd.get(), static_cast<off_t>(misc_offset), SEEK_SET) != |
73 | static_cast<off_t>(misc_offset)) { | ||
74 | *err = android::base::StringPrintf("failed to lseek %s: %s", misc_blk_device.c_str(), | ||
75 | strerror(errno)); | ||
76 | return false; | ||
77 | } | ||
78 | if (!android::base::WriteFully(fd.get(), p, size)) { | ||
73 | *err = android::base::StringPrintf("failed to write %s: %s", misc_blk_device.c_str(), | 79 | *err = android::base::StringPrintf("failed to write %s: %s", misc_blk_device.c_str(), |
74 | strerror(errno)); | 80 | strerror(errno)); |
75 | return false; | 81 | return false; |
76 | } | 82 | } |
83 | |||
77 | // TODO: O_SYNC and fsync duplicates each other? | 84 | // TODO: O_SYNC and fsync duplicates each other? |
78 | if (fsync(fd.get()) == -1) { | 85 | if (fsync(fd.get()) == -1) { |
79 | *err = android::base::StringPrintf("failed to fsync %s: %s", misc_blk_device.c_str(), | 86 | *err = android::base::StringPrintf("failed to fsync %s: %s", misc_blk_device.c_str(), |
@@ -83,6 +90,10 @@ static bool write_bootloader_message(const bootloader_message& boot, std::string | |||
83 | return true; | 90 | return true; |
84 | } | 91 | } |
85 | 92 | ||
93 | static bool write_bootloader_message(const bootloader_message& boot, std::string* err) { | ||
94 | return write_misc_partition(&boot, sizeof(boot), BOOTLOADER_MESSAGE_OFFSET_IN_MISC, err); | ||
95 | } | ||
96 | |||
86 | bool clear_bootloader_message(std::string* err) { | 97 | bool clear_bootloader_message(std::string* err) { |
87 | bootloader_message boot = {}; | 98 | bootloader_message boot = {}; |
88 | return write_bootloader_message(boot, err); | 99 | return write_bootloader_message(boot, err); |
@@ -101,6 +112,11 @@ bool write_bootloader_message(const std::vector<std::string>& options, std::stri | |||
101 | return write_bootloader_message(boot, err); | 112 | return write_bootloader_message(boot, err); |
102 | } | 113 | } |
103 | 114 | ||
115 | bool write_wipe_package(const std::string& package_data, std::string* err) { | ||
116 | return write_misc_partition(package_data.data(), package_data.size(), | ||
117 | WIPE_PACKAGE_OFFSET_IN_MISC, err); | ||
118 | } | ||
119 | |||
104 | extern "C" bool write_bootloader_message(const char* options) { | 120 | extern "C" bool write_bootloader_message(const char* options) { |
105 | std::string err; | 121 | std::string err; |
106 | return write_bootloader_message({options}, &err); | 122 | return write_bootloader_message({options}, &err); |
diff --git a/uncrypt/include/bootloader_message_writer.h b/uncrypt/include/bootloader_message_writer.h index e0ca3f44..1344bc83 100644 --- a/uncrypt/include/bootloader_message_writer.h +++ b/uncrypt/include/bootloader_message_writer.h | |||
@@ -24,6 +24,7 @@ | |||
24 | bool clear_bootloader_message(std::string* err); | 24 | bool clear_bootloader_message(std::string* err); |
25 | 25 | ||
26 | bool write_bootloader_message(const std::vector<std::string>& options, std::string* err); | 26 | bool write_bootloader_message(const std::vector<std::string>& options, std::string* err); |
27 | bool write_wipe_package(const std::string& package_data, std::string* err); | ||
27 | 28 | ||
28 | #else | 29 | #else |
29 | #include <stdbool.h> | 30 | #include <stdbool.h> |
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp index d7105a01..f62d1327 100644 --- a/uncrypt/uncrypt.cpp +++ b/uncrypt/uncrypt.cpp | |||
@@ -503,14 +503,31 @@ static bool setup_bcb(const int socket) { | |||
503 | return false; | 503 | return false; |
504 | } | 504 | } |
505 | ALOGI(" received command: [%s] (%zu)", content.c_str(), content.size()); | 505 | ALOGI(" received command: [%s] (%zu)", content.c_str(), content.size()); |
506 | std::vector<std::string> options = android::base::Split(content, "\n"); | ||
507 | std::string wipe_package; | ||
508 | for (auto& option : options) { | ||
509 | if (android::base::StartsWith(option, "--wipe_package=")) { | ||
510 | std::string path = option.substr(strlen("--wipe_package=")); | ||
511 | if (!android::base::ReadFileToString(path, &wipe_package)) { | ||
512 | ALOGE("failed to read %s: %s", path.c_str(), strerror(errno)); | ||
513 | return false; | ||
514 | } | ||
515 | option = android::base::StringPrintf("--wipe_package_size=%zu", wipe_package.size()); | ||
516 | } | ||
517 | } | ||
506 | 518 | ||
507 | // c8. setup the bcb command | 519 | // c8. setup the bcb command |
508 | std::string err; | 520 | std::string err; |
509 | if (!write_bootloader_message({content}, &err)) { | 521 | if (!write_bootloader_message(options, &err)) { |
510 | ALOGE("failed to set bootloader message: %s", err.c_str()); | 522 | ALOGE("failed to set bootloader message: %s", err.c_str()); |
511 | write_status_to_socket(-1, socket); | 523 | write_status_to_socket(-1, socket); |
512 | return false; | 524 | return false; |
513 | } | 525 | } |
526 | if (!wipe_package.empty() && !write_wipe_package(wipe_package, &err)) { | ||
527 | ALOGE("failed to set wipe package: %s", err.c_str()); | ||
528 | write_status_to_socket(-1, socket); | ||
529 | return false; | ||
530 | } | ||
514 | // c10. send "100" status | 531 | // c10. send "100" status |
515 | write_status_to_socket(100, socket); | 532 | write_status_to_socket(100, socket); |
516 | return true; | 533 | return true; |