summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordianlujitao <dianlujitao@lineageos.org>2018-12-03 11:45:47 +0100
committerEthan Yonker <dees_troy@teamw.in>2019-03-21 22:15:52 +0100
commit4879b37b5db3b06eb17a4a0deda5fc08fef51c41 (patch)
treeaf8ad951ba6b34091461debb35c755c1531b2ead
parentUse listbox for device-specific advanced menu items (diff)
downloadandroid_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-xAndroid.mk1
-rw-r--r--partition.cpp289
-rwxr-xr-xpartitionmanager.cpp2
-rw-r--r--partitions.hpp3
-rw-r--r--prebuilt/Android.mk3
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