summaryrefslogtreecommitdiff
path: root/fastboot/Fastboot.cpp
diff options
context:
space:
mode:
authorTommy Chiu <tommychiu@google.com>2021-10-08 16:09:03 +0800
committerTommy Chiu <tommychiu@google.com>2021-11-03 09:03:30 +0000
commitdb652e5dacfa493a6f9db7996e0cc642b97fdb9e (patch)
tree8ca4c5d85e97931844a11d10e040cb20956f22ca /fastboot/Fastboot.cpp
parent844f80597a864b39f7829bfb17482fd17c85f23f (diff)
fastbootd: erase "metadata" partition along with "erase userdata" command
On erasing userdata partition, all the related partitions (ex, metadata) need to be erased respectively. Otherwise vold will get an error while trying to decrypt the leftover materials on the next bootup. Bug: 201533761 Test: fastboot erase userdata and reboot device Change-Id: If299d43f6d8fc9e092d2229022abc29383698320
Diffstat (limited to 'fastboot/Fastboot.cpp')
-rw-r--r--fastboot/Fastboot.cpp72
1 files changed, 67 insertions, 5 deletions
diff --git a/fastboot/Fastboot.cpp b/fastboot/Fastboot.cpp
index 93435d6..922334b 100644
--- a/fastboot/Fastboot.cpp
+++ b/fastboot/Fastboot.cpp
@@ -19,11 +19,19 @@
#include <string>
#include <unordered_map>
#include <vector>
+#include <map>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
+
+// FS headers
+#include <ext4_utils/wipe.h>
+#include <fs_mgr.h>
+#include <fs_mgr/roots.h>
+
+// Nugget headers
#include <app_nugget.h>
#include <nos/NuggetClient.h>
#include <nos/debug.h>
@@ -122,7 +130,50 @@ Return<void> Fastboot::doOemCommand(const ::android::hardware::hidl_string& oemC
return Void();
}
+static android::fs_mgr::Fstab fstab;
+enum WipeVolumeStatus {
+ WIPE_OK = 0,
+ VOL_FSTAB,
+ VOL_UNKNOWN,
+ VOL_MOUNTED,
+ VOL_BLK_DEV_OPEN,
+ WIPE_ERROR_MAX = 0xffffffff,
+};
+std::map<enum WipeVolumeStatus, std::string> wipe_vol_ret_msg{
+ {WIPE_OK, ""},
+ {VOL_FSTAB, "Unknown FS table"},
+ {VOL_UNKNOWN, "Unknown volume"},
+ {VOL_MOUNTED, "Fail to unmount volume"},
+ {VOL_BLK_DEV_OPEN, "Fail to open block device"},
+ {WIPE_ERROR_MAX, "Unknown wipe error"}};
+
+enum WipeVolumeStatus wipe_volume(const std::string &volume) {
+ if (!android::fs_mgr::ReadDefaultFstab(&fstab)) {
+ return VOL_FSTAB;
+ }
+ const fs_mgr::FstabEntry *v = android::fs_mgr::GetEntryForPath(&fstab, volume);
+ if (v == nullptr) {
+ return VOL_UNKNOWN;
+ }
+ if (android::fs_mgr::EnsurePathUnmounted(&fstab, volume) != true) {
+ return VOL_MOUNTED;
+ }
+
+ int fd = open(v->blk_device.c_str(), O_WRONLY | O_CREAT, 0644);
+ if (fd == -1) {
+ return VOL_BLK_DEV_OPEN;
+ }
+ wipe_block_device(fd, get_block_device_size(fd));
+ close(fd);
+
+ return WIPE_OK;
+}
+
Return<void> Fastboot::doOemSpecificErase(V1_1::IFastboot::doOemSpecificErase_cb _hidl_cb) {
+ // Erase metadata partition along with userdata partition.
+ // Keep erasing Titan M even if failing on this case.
+ auto wipe_status = wipe_volume("/metadata");
+
// Connect to Titan M
::nos::NuggetClient client;
client.Open();
@@ -136,16 +187,27 @@ Return<void> Fastboot::doOemSpecificErase(V1_1::IFastboot::doOemSpecificErase_cb
std::vector<uint8_t> magic(sizeof(magicValue));
memcpy(magic.data(), &magicValue, sizeof(magicValue));
const uint8_t retry_count = 5;
+ uint32_t nugget_status;
for(uint8_t i = 0; i < retry_count; i++) {
- const uint32_t status
- = client.CallApp(APP_ID_NUGGET, NUGGET_PARAM_NUKE_FROM_ORBIT, magic, nullptr);
- if (status == APP_SUCCESS) {
- _hidl_cb({ Status::SUCCESS, "" });
+ nugget_status = client.CallApp(APP_ID_NUGGET, NUGGET_PARAM_NUKE_FROM_ORBIT, magic, nullptr);
+ if (nugget_status == APP_SUCCESS && wipe_status == WIPE_OK) {
+ _hidl_cb({Status::SUCCESS, wipe_vol_ret_msg[wipe_status]});
return Void();
}
}
- _hidl_cb({ Status::FAILURE_UNKNOWN, "Titan M user data wipe failed" });
+ // Return exactly what happened
+ if (nugget_status != APP_SUCCESS && wipe_status != WIPE_OK) {
+ _hidl_cb({Status::FAILURE_UNKNOWN, "Fail on wiping metadata and Titan M user data"});
+ } else if (nugget_status != APP_SUCCESS) {
+ _hidl_cb({Status::FAILURE_UNKNOWN, "Titan M user data wipe failed"});
+ } else {
+ if (wipe_vol_ret_msg.find(wipe_status) != wipe_vol_ret_msg.end())
+ _hidl_cb({Status::FAILURE_UNKNOWN, wipe_vol_ret_msg[wipe_status]});
+ else // Should not reach here, but handle it anyway
+ _hidl_cb({Status::FAILURE_UNKNOWN, "Unknown failure"});
+ }
+
return Void();
}