summaryrefslogtreecommitdiff
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
parent844f80597a864b39f7829bfb17482fd17c85f23f (diff)
downloadpixel-db652e5dacfa493a6f9db7996e0cc642b97fdb9e.tar.gz
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
-rw-r--r--fastboot/Android.bp10
-rw-r--r--fastboot/Fastboot.cpp72
2 files changed, 73 insertions, 9 deletions
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index c40b69f7..dd2f80da 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -26,13 +26,15 @@ cc_library {
relative_install_path: "hw",
export_include_dirs: ["include"],
shared_libs: [
- "liblog",
+ "android.hardware.fastboot@1.0",
+ "android.hardware.fastboot@1.1",
"libbase",
+ "libcutils",
+ "libext4_utils",
+ "libfs_mgr",
"libhidlbase",
+ "liblog",
"libutils",
- "libcutils",
- "android.hardware.fastboot@1.0",
- "android.hardware.fastboot@1.1",
],
static_libs: [
"libnos_for_fastboot",
diff --git a/fastboot/Fastboot.cpp b/fastboot/Fastboot.cpp
index 93435d69..922334b4 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();
}