diff options
author | dianlujitao <dianlujitao@lineageos.org> | 2018-12-03 11:45:47 +0100 |
---|---|---|
committer | Ethan Yonker <dees_troy@teamw.in> | 2019-03-21 22:15:52 +0100 |
commit | 4879b37b5db3b06eb17a4a0deda5fc08fef51c41 (patch) | |
tree | af8ad951ba6b34091461debb35c755c1531b2ead | |
parent | Use listbox for device-specific advanced menu items (diff) | |
download | android_bootable_recovery-4879b37b5db3b06eb17a4a0deda5fc08fef51c41.tar android_bootable_recovery-4879b37b5db3b06eb17a4a0deda5fc08fef51c41.tar.gz android_bootable_recovery-4879b37b5db3b06eb17a4a0deda5fc08fef51c41.tar.bz2 android_bootable_recovery-4879b37b5db3b06eb17a4a0deda5fc08fef51c41.tar.lz android_bootable_recovery-4879b37b5db3b06eb17a4a0deda5fc08fef51c41.tar.xz android_bootable_recovery-4879b37b5db3b06eb17a4a0deda5fc08fef51c41.tar.zst android_bootable_recovery-4879b37b5db3b06eb17a4a0deda5fc08fef51c41.zip |
-rwxr-xr-x | Android.mk | 1 | ||||
-rw-r--r-- | partition.cpp | 289 | ||||
-rwxr-xr-x | partitionmanager.cpp | 2 | ||||
-rw-r--r-- | partitions.hpp | 3 | ||||
-rw-r--r-- | prebuilt/Android.mk | 3 |
5 files changed, 178 insertions, 120 deletions
diff --git a/Android.mk b/Android.mk index 920b3903b..6eb1cbcd5 100755 --- a/Android.mk +++ b/Android.mk @@ -46,6 +46,7 @@ ifneq ($(TW_DEVICE_VERSION),) else LOCAL_CFLAGS += -DTW_DEVICE_VERSION='"-0"' endif +LOCAL_CFLAGS += -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) LOCAL_SRC_FILES := \ twrp.cpp \ diff --git a/partition.cpp b/partition.cpp index b96b969be..b421598b8 100644 --- a/partition.cpp +++ b/partition.cpp @@ -258,7 +258,7 @@ TWPartition::TWPartition() { Format_Block_Size = 0; Ignore_Blkid = false; Retain_Layout_Version = false; - Crypto_Key_Location = "footer"; + Crypto_Key_Location = ""; MTP_Storage_ID = 0; Can_Flash_Img = false; Mount_Read_Only = false; @@ -1603,7 +1603,7 @@ bool TWPartition::Wipe(string New_File_System) { else if (New_File_System == "ext4") wiped = Wipe_EXT4(); else if (New_File_System == "ext2" || New_File_System == "ext3") - wiped = Wipe_EXT23(New_File_System); + wiped = Wipe_EXTFS(New_File_System); else if (New_File_System == "vfat") wiped = Wipe_FAT(); else if (New_File_System == "exfat") @@ -1931,68 +1931,26 @@ bool TWPartition::Wipe_Encryption() { if (!base_partition->PreWipeEncryption()) goto exit; + Find_Actual_Block_Device(); + if (!Is_Present) { + LOGINFO("Block device not present, cannot format %s.\n", Display_Name.c_str()); + gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name)); + return false; + } if (!UnMount(true)) goto exit; - Has_Data_Media = false; #ifdef TW_INCLUDE_CRYPTO if (Is_Decrypted && !Decrypted_Block_Device.empty()) { - if (!UnMount(true)) - goto exit; if (delete_crypto_blk_dev((char*)("userdata")) != 0) { LOGERR("Error deleting crypto block device, continuing anyway.\n"); } } #endif + Has_Data_Media = false; Decrypted_Block_Device = ""; Is_Decrypted = false; Is_Encrypted = false; - Find_Actual_Block_Device(); - if (Crypto_Key_Location == "footer") { - int newlen, fd; - if (Length != 0) { - newlen = Length; - if (newlen < 0) - newlen = newlen * -1; - } else { - newlen = CRYPT_FOOTER_OFFSET; - } - if ((fd = open(Actual_Block_Device.c_str(), O_RDWR)) < 0) { - gui_print_color("warning", "Unable to open '%s' to wipe crypto key\n", Actual_Block_Device.c_str()); - } else { - unsigned int block_count; - if ((ioctl(fd, BLKGETSIZE, &block_count)) == -1) { - gui_print_color("warning", "Unable to get block size for wiping crypto footer.\n"); - } else { - off64_t offset = ((off64_t)block_count * 512) - newlen; - if (lseek64(fd, offset, SEEK_SET) == -1) { - gui_print_color("warning", "Unable to lseek64 for wiping crypto footer.\n"); - } else { - void* buffer = malloc(newlen); - if (!buffer) { - gui_print_color("warning", "Failed to malloc for wiping crypto footer.\n"); - } else { - memset(buffer, 0, newlen); - int ret = write(fd, buffer, newlen); - if (ret != newlen) { - gui_print_color("warning", "Failed to wipe crypto footer.\n"); - } else { - LOGINFO("Successfully wiped crypto footer.\n"); - } - free(buffer); - } - } - } - close(fd); - } - } else { - if (TWFunc::IOCTL_Get_Block_Size(Crypto_Key_Location.c_str()) >= 16384LLU) { - string Command = "dd of='" + Crypto_Key_Location + "' if=/dev/zero bs=16384 count=1"; - TWFunc::Exec_Cmd(Command); - } else { - LOGINFO("Crypto key location reports size < 16K so not wiping crypto footer.\n"); - } - } if (Wipe(Fstab_File_System)) { Has_Data_Media = Save_Data_Media; if (Has_Data_Media && !Symlink_Mount_Point.empty()) { @@ -2067,33 +2025,82 @@ void TWPartition::Check_FS_Type() { } } -bool TWPartition::Wipe_EXT23(string File_System) { +bool TWPartition::Wipe_EXTFS(string File_System) { +#if PLATFORM_SDK_VERSION < 28 + if (!TWFunc::Path_Exists("/sbin/mke2fs")) +#else + if (!TWFunc::Path_Exists("/sbin/mke2fs") || !TWFunc::Path_Exists("/sbin/e2fsdroid")) +#endif + return Wipe_RMRF(); + + int ret; + bool NeedPreserveFooter = true; + + Find_Actual_Block_Device(); + if (!Is_Present) { + LOGINFO("Block device not present, cannot wipe %s.\n", Display_Name.c_str()); + gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name)); + return false; + } if (!UnMount(true)) return false; - if (TWFunc::Path_Exists("/sbin/mke2fs")) { - string command; + /** + * On decrypted devices, IOCTL_Get_Block_Size calculates size on device mapper, + * so there's no need to preserve footer. + */ + if ((Is_Decrypted && !Decrypted_Block_Device.empty()) || + Crypto_Key_Location != "footer") { + NeedPreserveFooter = false; + } - gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("mke2fs")); - Find_Actual_Block_Device(); - command = "mke2fs -t " + File_System + " -m 0 " + Actual_Block_Device; - LOGINFO("mke2fs command: %s\n", command.c_str()); - if (TWFunc::Exec_Cmd(command) == 0) { - Current_File_System = File_System; - Recreate_AndSec_Folder(); - gui_msg("done=Done."); - return true; - } else { + unsigned long long dev_sz = TWFunc::IOCTL_Get_Block_Size(Actual_Block_Device.c_str()); + if (!dev_sz) + return false; + + if (NeedPreserveFooter) + Length < 0 ? dev_sz += Length : dev_sz -= CRYPT_FOOTER_OFFSET; + + string size_str = to_string(dev_sz / 4096); + string Command; + + gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("mke2fs")); + + // Execute mke2fs to create empty ext4 filesystem + Command = "mke2fs -t " + File_System + " -b 4096 " + Actual_Block_Device + " " + size_str; + LOGINFO("mke2fs command: %s\n", Command.c_str()); + ret = TWFunc::Exec_Cmd(Command); + if (ret) { + gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name)); + return false; + } + + if (TWFunc::Path_Exists("/sbin/e2fsdroid")) { + // Execute e2fsdroid to initialize selinux context + Command = "e2fsdroid -e -a " + Mount_Point + " " + Actual_Block_Device; + LOGINFO("e2fsdroid command: %s\n", Command.c_str()); + ret = TWFunc::Exec_Cmd(Command); + if (ret) { gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name)); return false; } - } else - return Wipe_RMRF(); + } else { + LOGINFO("e2fsdroid not present\n"); + } - return false; + if (NeedPreserveFooter) + Wipe_Crypto_Key(); + Current_File_System = File_System; + Recreate_AndSec_Folder(); + gui_msg("done=Done."); + return true; } bool TWPartition::Wipe_EXT4() { +#ifdef USE_EXT4 + int ret; + bool NeedPreserveFooter = true; + Find_Actual_Block_Device(); if (!Is_Present) { LOGINFO("Block device not present, cannot wipe %s.\n", Display_Name.c_str()); @@ -2103,22 +2110,38 @@ bool TWPartition::Wipe_EXT4() { if (!UnMount(true)) return false; -#if defined(USE_EXT4) - int ret; + /** + * On decrypted devices, IOCTL_Get_Block_Size calculates size on device mapper, + * so there's no need to preserve footer. + */ + if ((Is_Decrypted && !Decrypted_Block_Device.empty()) || + Crypto_Key_Location != "footer") { + NeedPreserveFooter = false; + } + + unsigned long long dev_sz = TWFunc::IOCTL_Get_Block_Size(Actual_Block_Device.c_str()); + if (!dev_sz) + return false; + + if (NeedPreserveFooter) + Length < 0 ? dev_sz += Length : dev_sz -= CRYPT_FOOTER_OFFSET; + char *secontext = NULL; gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("make_ext4fs")); if (!selinux_handle || selabel_lookup(selinux_handle, &secontext, Mount_Point.c_str(), S_IFDIR) < 0) { LOGINFO("Cannot lookup security context for '%s'\n", Mount_Point.c_str()); - ret = make_ext4fs(Actual_Block_Device.c_str(), Length, Mount_Point.c_str(), NULL); + ret = make_ext4fs(Actual_Block_Device.c_str(), dev_sz, Mount_Point.c_str(), NULL); } else { - ret = make_ext4fs(Actual_Block_Device.c_str(), Length, Mount_Point.c_str(), selinux_handle); + ret = make_ext4fs(Actual_Block_Device.c_str(), dev_sz, Mount_Point.c_str(), selinux_handle); } if (ret != 0) { gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name)); return false; } else { + if (NeedPreserveFooter) + Wipe_Crypto_Key(); string sedir = Mount_Point + "/lost+found"; PartitionManager.Mount_By_Path(sedir.c_str(), true); rmdir(sedir.c_str()); @@ -2126,37 +2149,8 @@ bool TWPartition::Wipe_EXT4() { return true; } #else - if (TWFunc::Path_Exists("/sbin/make_ext4fs")) { - string Command; - - gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("make_ext4fs")); - Find_Actual_Block_Device(); - Command = "make_ext4fs"; - if (!Is_Decrypted && Length != 0) { - // Only use length if we're not decrypted - char len[32]; - sprintf(len, "%i", Length); - Command += " -l "; - Command += len; - } - if (TWFunc::Path_Exists("/file_contexts")) { - Command += " -S /file_contexts"; - } - Command += " -a " + Mount_Point + " " + Actual_Block_Device; - LOGINFO("make_ext4fs command: %s\n", Command.c_str()); - if (TWFunc::Exec_Cmd(Command) == 0) { - Current_File_System = "ext4"; - Recreate_AndSec_Folder(); - gui_msg("done=Done."); - return true; - } else { - gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name)); - return false; - } - } else - return Wipe_EXT23("ext4"); + return Wipe_EXTFS("ext4"); #endif - return false; } bool TWPartition::Wipe_FAT() { @@ -2261,29 +2255,42 @@ bool TWPartition::Wipe_F2FS() { string command; if (TWFunc::Path_Exists("/sbin/mkfs.f2fs")) { + bool NeedPreserveFooter = true; + + Find_Actual_Block_Device(); + if (!Is_Present) { + LOGINFO("Block device not present, cannot wipe %s.\n", Display_Name.c_str()); + gui_msg(Msg(msg::kError, "unable_to_wipe=Unable to wipe {1}.")(Display_Name)); + return false; + } if (!UnMount(true)) return false; + /** + * On decrypted devices, IOCTL_Get_Block_Size calculates size on device mapper, + * so there's no need to preserve footer. + */ + if ((Is_Decrypted && !Decrypted_Block_Device.empty()) || + Crypto_Key_Location != "footer") { + NeedPreserveFooter = false; + } + + unsigned long long dev_sz = TWFunc::IOCTL_Get_Block_Size(Actual_Block_Device.c_str()); + if (!dev_sz) + return false; + + if (NeedPreserveFooter) + Length < 0 ? dev_sz += Length : dev_sz -= CRYPT_FOOTER_OFFSET; + gui_msg(Msg("formatting_using=Formatting {1} using {2}...")(Display_Name)("mkfs.f2fs")); - Find_Actual_Block_Device(); - if (!TWFunc::Path_Exists("/sbin/sload.f2fs")) { - command = "mkfs.f2fs -t 0"; - if (!Is_Decrypted && Length != 0) { - // Only use length if we're not decrypted - char len[32]; - int mod_length = Length; - if (Length < 0) - mod_length *= -1; - sprintf(len, "%i", mod_length); - command += " -r "; - command += len; - } - command += " " + Actual_Block_Device; - } else { - unsigned long long size = IOCTL_Get_Block_Size() + Length; - command = "mkfs.f2fs -d1 -f -O encrypt -O quota -O verity -w 4096 " + Actual_Block_Device + " " + std::to_string(size / 4096) + " && sload.f2fs -t /data " + Actual_Block_Device; + command = "mkfs.f2fs -d1 -f -O encrypt -O quota -O verity -w 4096 " + Actual_Block_Device + " " + to_string(dev_sz / 4096); + if (TWFunc::Path_Exists("/sbin/sload.f2fs")) { + command += " && sload.f2fs -t /data " + Actual_Block_Device; } + LOGINFO("mkfs.f2fs command: %s\n", command.c_str()); if (TWFunc::Exec_Cmd(command) == 0) { + if (NeedPreserveFooter) + Wipe_Crypto_Key(); Recreate_AndSec_Folder(); gui_msg("done=Done."); return true; @@ -2381,6 +2388,52 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media_Func(const string& parent __unu return false; } +void TWPartition::Wipe_Crypto_Key() { + Find_Actual_Block_Device(); + if (Crypto_Key_Location.empty()) + return; + else if (Crypto_Key_Location == "footer") { + int fd = open(Actual_Block_Device.c_str(), O_RDWR); + if (fd < 0) { + gui_print_color("warning", "Unable to open '%s' to wipe crypto key\n", Actual_Block_Device.c_str()); + return; + } + + unsigned int block_count; + if ((ioctl(fd, BLKGETSIZE, &block_count)) == -1) { + gui_print_color("warning", "Unable to get block size for wiping crypto footer.\n"); + } else { + int newlen = Length < 0 ? -Length : CRYPT_FOOTER_OFFSET; + off64_t offset = ((off64_t)block_count * 512) - newlen; + if (lseek64(fd, offset, SEEK_SET) == -1) { + gui_print_color("warning", "Unable to lseek64 for wiping crypto footer.\n"); + } else { + void* buffer = malloc(newlen); + if (!buffer) { + gui_print_color("warning", "Failed to malloc for wiping crypto footer.\n"); + } else { + memset(buffer, 0, newlen); + int ret = write(fd, buffer, newlen); + if (ret != newlen) { + gui_print_color("warning", "Failed to wipe crypto footer.\n"); + } else { + LOGINFO("Successfully wiped crypto footer.\n"); + } + free(buffer); + } + } + } + close(fd); + } else { + if (TWFunc::IOCTL_Get_Block_Size(Crypto_Key_Location.c_str()) >= 16384LLU) { + string Command = "dd of='" + Crypto_Key_Location + "' if=/dev/zero bs=16384 count=1"; + TWFunc::Exec_Cmd(Command); + } else { + LOGINFO("Crypto key location reports size < 16K so not wiping crypto footer.\n"); + } + } +} + bool TWPartition::Backup_Tar(PartitionSettings *part_settings, pid_t *tar_fork_pid) { string Full_FileName; twrpTar tar; diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 4ebe7427d..6b5ee1cca 100755 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -466,7 +466,7 @@ void TWPartitionManager::Output_Partition(TWPartition* Part) { printf(" Alternate_Block_Device: %s\n", Part->Alternate_Block_Device.c_str()); if (!Part->Decrypted_Block_Device.empty()) printf(" Decrypted_Block_Device: %s\n", Part->Decrypted_Block_Device.c_str()); - if (!Part->Crypto_Key_Location.empty() && Part->Crypto_Key_Location != "footer") + if (!Part->Crypto_Key_Location.empty()) printf(" Crypto_Key_Location: %s\n", Part->Crypto_Key_Location.c_str()); if (Part->Length != 0) printf(" Length: %i\n", Part->Length); diff --git a/partitions.hpp b/partitions.hpp index a8fd70b40..c124457f6 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -181,7 +181,7 @@ private: unsigned long long IOCTL_Get_Block_Size(); // Finds the partition size using ioctl bool Find_Partition_Size(); // Finds the partition size from /proc/partitions unsigned long long Get_Size_Via_du(string Path, bool Display_Error); // Uses du to get sizes - bool Wipe_EXT23(string File_System); // Formats as ext3 or ext2 + bool Wipe_EXTFS(string File_System); // Create an ext2/ext3/ext4 filesystem bool Wipe_EXT4(); // Formats using ext4, uses make_ext4fs when present bool Wipe_FAT(); // Formats as FAT if mkfs.fat exits otherwise rm -rf wipe bool Wipe_EXFAT(); // Formats as EXFAT @@ -191,6 +191,7 @@ private: bool Wipe_NTFS(); // Uses mkntfs to wipe bool Wipe_Data_Without_Wiping_Media(); // Uses rm -rf to wipe but does not wipe /data/media bool Wipe_Data_Without_Wiping_Media_Func(const string& parent); // Uses rm -rf to wipe but does not wipe /data/media + void Wipe_Crypto_Key(); // Wipe crypto key from either footer or block device bool Backup_Tar(PartitionSettings *part_settings, pid_t *tar_fork_pid); // Backs up using tar for file systems bool Backup_Image(PartitionSettings *part_settings); // Backs up using raw read/write for emmc memory types bool Raw_Read_Write(PartitionSettings *part_settings); diff --git a/prebuilt/Android.mk b/prebuilt/Android.mk index 7696affc4..de8287937 100644 --- a/prebuilt/Android.mk +++ b/prebuilt/Android.mk @@ -41,6 +41,9 @@ ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 27; echo $$?),0) RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/adbd endif RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/e2fsck +ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 28; echo $$?),0) + RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/e2fsdroid +endif RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/mke2fs RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/tune2fs RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/resize2fs |