diff options
author | Tommy Chiu <tommychiu@google.com> | 2021-10-08 16:09:03 +0800 |
---|---|---|
committer | Tommy Chiu <tommychiu@google.com> | 2021-11-03 09:03:30 +0000 |
commit | db652e5dacfa493a6f9db7996e0cc642b97fdb9e (patch) | |
tree | 8ca4c5d85e97931844a11d10e040cb20956f22ca | |
parent | 844f80597a864b39f7829bfb17482fd17c85f23f (diff) | |
download | pixel-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.bp | 10 | ||||
-rw-r--r-- | fastboot/Fastboot.cpp | 72 |
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(); } |