From 38b83c1da45f0b4a7d166bee73dc7701794874c3 Mon Sep 17 00:00:00 2001 From: bigbiff bigbiff Date: Thu, 28 Dec 2017 19:58:52 -0500 Subject: ADB Backup: fix md5 check on restore. Add debug capability. Fix backup of images after tarred partitions with too much padding Add more md5 logging. Skip digest check if selected. Change ADB Backup version to 3 for new fixes to image padding. Change-Id: I0f76c0733c523717e4797d1a14c3ae47d046fc8c --- adbbu/Android.mk | 2 +- adbbu/libtwadbbu.cpp | 2 +- adbbu/twadbstream.h | 2 +- adbbu/twrpback.cpp | 296 +++++++++++++++++++++++++++++++++------------------ adbbu/twrpback.hpp | 2 + partition.cpp | 3 +- twrpAdbBuFifo.cpp | 77 ++++++++------ 7 files changed, 246 insertions(+), 138 deletions(-) diff --git a/adbbu/Android.mk b/adbbu/Android.mk index efb5f9ae5..8f8dbd0fb 100644 --- a/adbbu/Android.mk +++ b/adbbu/Android.mk @@ -3,7 +3,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libtwadbbu LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS = -fno-strict-aliasing -D_LARGFILE_SOURCE +LOCAL_CFLAGS = -fno-strict-aliasing -D_LARGFILE_SOURCE #-D_DEBUG_ADB_BACKUP LOCAL_C_INCLUDES += bionic external/zlib ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0) LOCAL_C_INCLUDES += external/stlport/stlport diff --git a/adbbu/libtwadbbu.cpp b/adbbu/libtwadbbu.cpp index 64e688c37..39803b0ce 100644 --- a/adbbu/libtwadbbu.cpp +++ b/adbbu/libtwadbbu.cpp @@ -75,7 +75,7 @@ std::vector twadbbu::Get_ADB_Backup_Files(std::string fname) { return std::vector(); } - while (1) { + while (true) { std::string cmdstr; int readbytes; if ((readbytes = read(fd, &buf, sizeof(buf))) > 0) { diff --git a/adbbu/twadbstream.h b/adbbu/twadbstream.h index fd8eba9f4..bef463cf8 100644 --- a/adbbu/twadbstream.h +++ b/adbbu/twadbstream.h @@ -39,7 +39,7 @@ #define TWMD5 "twverifymd5" //This command is compared to the md5trailer by ORS to verify transfer #define TWENDADB "twendadb" //End Protocol #define TWERROR "twerror" //Send error -#define ADB_BACKUP_VERSION 2 //Backup Version +#define ADB_BACKUP_VERSION 3 //Backup Version #define DATA_MAX_CHUNK_SIZE 1048576 //Maximum size between each data header #define MAX_ADB_READ 512 //align with default tar size for amount to read fom adb stream diff --git a/adbbu/twrpback.cpp b/adbbu/twrpback.cpp index d88a9c9da..56bc13d48 100644 --- a/adbbu/twrpback.cpp +++ b/adbbu/twrpback.cpp @@ -42,14 +42,15 @@ #include "../twrpAdbBuFifo.hpp" twrpback::twrpback(void) { + adbd_fp = NULL; read_fd = 0; write_fd = 0; adb_control_twrp_fd = 0; adb_control_bu_fd = 0; adb_read_fd = 0; adb_write_fd = 0; - adb_write_fd = 0; ors_fd = 0; + debug_adb_fd = 0; firstPart = true; createFifos(); adbloginit(); @@ -60,30 +61,32 @@ twrpback::~twrpback(void) { closeFifos(); } +void twrpback::printErrMsg(std::string msg, int errNum) { + std::stringstream str; + str << strerror(errNum); + adblogwrite(msg + " " + str.str() + "\n"); +} + void twrpback::createFifos(void) { if (mkfifo(TW_ADB_BU_CONTROL, 0666) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Unable to create TW_ADB_BU_CONTROL fifo: " + str.str() + "\n"); + std::string msg = "Unable to create TW_ADB_BU_CONTROL fifo: "; + printErrMsg(msg, errno); } if (mkfifo(TW_ADB_TWRP_CONTROL, 0666) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Unable to create TW_ADB_TWRP_CONTROL fifo: " + str.str() + "\n"); + std::string msg = "Unable to create TW_ADB_TWRP_CONTROL fifo: "; + printErrMsg(msg, errno); unlink(TW_ADB_BU_CONTROL); } } void twrpback::closeFifos(void) { if (unlink(TW_ADB_BU_CONTROL) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Unable to remove TW_ADB_BU_CONTROL: " + str.str()); + std::string msg = "Unable to remove TW_ADB_BU_CONTROL: "; + printErrMsg(msg, errno); } if (unlink(TW_ADB_TWRP_CONTROL) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Unable to remove TW_ADB_TWRP_CONTROL: " + str.str()); + std::string msg = "Unable to remove TW_ADB_TWRP_CONTROL: "; + printErrMsg(msg, errno); } } @@ -104,6 +107,10 @@ void twrpback::close_backup_fds() { close(adb_read_fd); if (adb_control_bu_fd > 0) close(adb_control_bu_fd); + #ifdef _DEBUG_ADB_BACKUP + if (debug_adb_fd > 0) + close(debug_adb_fd); + #endif if (adbd_fp != NULL) fclose(adbd_fp); if (access(TW_ADB_BACKUP, F_OK) == 0) @@ -123,15 +130,17 @@ void twrpback::close_restore_fds() { fclose(adbd_fp); if (access(TW_ADB_RESTORE, F_OK) == 0) unlink(TW_ADB_RESTORE); + #ifdef _DEBUG_ADB_BACKUP + if (debug_adb_fd > 0) + close(debug_adb_fd); + #endif } bool twrpback::backup(std::string command) { twrpMD5 digest; - bool breakloop = false; int bytes = 0, errctr = 0; char adbReadStream[MAX_ADB_READ]; uint64_t totalbytes = 0, dataChunkBytes = 0, fileBytes = 0; - int64_t count = false; // Count of how many blocks set uint64_t md5fnsize = 0; struct AdbBackupControlType endadb; @@ -153,13 +162,15 @@ bool twrpback::backup(std::string command) { } adblogwrite("opening TW_ADB_FIFO\n"); + write_fd = open(TW_ADB_FIFO, O_WRONLY); while (write_fd < 0) { write_fd = open(TW_ADB_FIFO, O_WRONLY); usleep(10000); errctr++; if (errctr > ADB_BU_MAX_ERROR) { - adblogwrite("Unable to open TW_ADB_FIFO\n"); + std::string msg = "Unable to open TW_ADB_FIFO"; + printErrMsg(msg, errno); close_backup_fds(); return false; } @@ -197,7 +208,7 @@ bool twrpback::backup(std::string command) { } //loop until TWENDADB sent - while (!breakloop) { + while (true) { if (read(adb_control_bu_fd, &cmd, sizeof(cmd)) > 0) { struct AdbBackupControlType structcmd; @@ -219,16 +230,15 @@ bool twrpback::backup(std::string command) { std::stringstream str; str << totalbytes; adblogwrite(str.str() + " total bytes written\n"); - breakloop = true; + break; } //we recieved the TWSTREAMHDR structure metadata to write to adb else if (cmdtype == TWSTREAMHDR) { writedata = false; adblogwrite("writing TWSTREAMHDR\n"); if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Error writing TWSTREAMHDR to adbd" + str.str() + "\n"); + std::string msg = "Error writing TWSTREAMHDR to adbd"; + printErrMsg(msg, errno); close_backup_fds(); return false; } @@ -245,6 +255,14 @@ bool twrpback::backup(std::string command) { md5fnsize = twimghdr.size; compressed = false; + #ifdef _DEBUG_ADB_BACKUP + std::string debug_fname = "/data/media/"; + debug_fname.append(basename(twimghdr.name)); + debug_fname.append("-backup.img"); + debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666); + adblogwrite("Opening adb debug tar\n"); + #endif + if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { adblogwrite("Error writing TWIMG to adbd\n"); close_backup_fds(); @@ -268,6 +286,14 @@ bool twrpback::backup(std::string command) { compressed = twfilehdr.compressed == 1 ? true: false; + #ifdef _DEBUG_ADB_BACKUP + std::string debug_fname = "/data/media/"; + debug_fname.append(basename(twfilehdr.name)); + debug_fname.append("-backup.tar"); + debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666); + adblogwrite("Opening adb debug tar\n"); + #endif + if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { adblogwrite("Error writing TWFN to adbd\n"); close_backup_fds(); @@ -296,30 +322,44 @@ bool twrpback::backup(std::string command) { digest.update((unsigned char *) writeAdbReadStream, bytes); if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adbd stream: " + str.str() + "\n"); + std::string msg = "Cannot write to adbd stream: "; + printErrMsg(msg, errno); + } + #if defined(_DEBUG_ADB_BACKUP) + if (write(debug_adb_fd, writeAdbReadStream, bytes) < 1) { + std::string msg = "Cannot write to ADB_CONTROL_READ_FD: "; + printErrMsg(msg, errno); + close_restore_fds(); + return false; } + #endif fflush(adbd_fp); delete [] writeAdbReadStream; memset(adbReadStream, 0, sizeof(adbReadStream)); } - count = fileBytes / DATA_MAX_CHUNK_SIZE + 1; - count = count * DATA_MAX_CHUNK_SIZE; - if (fileBytes % DATA_MAX_CHUNK_SIZE != 0) { - char padding[count - fileBytes]; + int64_t count = fileBytes / DATA_MAX_CHUNK_SIZE + 1; + uint64_t ceilingBytes = count * DATA_MAX_CHUNK_SIZE; + char padding[ceilingBytes - fileBytes]; int paddingBytes = sizeof(padding); + memset(padding, 0, paddingBytes); std::stringstream paddingStr; paddingStr << paddingBytes; - memset(padding, 0, paddingBytes); adblogwrite("writing padding to stream: " + paddingStr.str() + " bytes\n"); if (fwrite(padding, 1, paddingBytes, adbd_fp) != sizeof(padding)) { adblogwrite("Error writing padding to adbd\n"); close_backup_fds(); return false; } + #if defined(_DEBUG_ADB_BACKUP) + if (write(debug_adb_fd, padding, paddingBytes) < 1) { + std::string msg = "Cannot write to ADB_CONTROL_READ_FD: "; + printErrMsg(msg, errno); + close_restore_fds(); + return false; + } + #endif totalbytes += paddingBytes; digest.update((unsigned char *) padding, paddingBytes); fflush(adbd_fp); @@ -353,6 +393,7 @@ bool twrpback::backup(std::string command) { fileBytes = 0; } memset(&cmd, 0, sizeof(cmd)); + dataChunkBytes = 0; } //If we are to write data because of a new file stream, lets write all the data. //This will allow us to not write data after a command structure has been written @@ -365,6 +406,7 @@ bool twrpback::backup(std::string command) { close_backup_fds(); return false; } + fileBytes += MAX_ADB_READ; fflush(adbd_fp); firstDataPacket = false; dataChunkBytes += sizeof(adbReadStream); @@ -383,6 +425,14 @@ bool twrpback::backup(std::string command) { close_backup_fds(); return false; } + #ifdef _DEBUG_ADB_BACKUP + if (write(debug_adb_fd, writeAdbReadStream, bytes) < 1) { + std::string msg = "Cannot write to ADB_CONTROL_READ_FD: "; + printErrMsg(msg, errno); + close_restore_fds(); + return false; + } + #endif fflush(adbd_fp); delete [] writeAdbReadStream; @@ -409,12 +459,19 @@ bool twrpback::backup(std::string command) { digest.update((unsigned char *) writeAdbReadStream, bytes); if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adbd stream: " + str.str() + "\n"); + std::string msg = "Cannot write to adbd stream: "; + printErrMsg(msg, errno); close_restore_fds(); return false; } + #ifdef _DEBUG_ADB_BACKUP + if (write(debug_adb_fd, writeAdbReadStream, bytes) < 1) { + std::string msg = "Cannot write to ADB_CONTROL_READ_FD: "; + printErrMsg(msg, errno); + close_restore_fds(); + return false; + } + #endif fflush(adbd_fp); delete [] writeAdbReadStream; } @@ -440,7 +497,7 @@ bool twrpback::backup(std::string command) { } fflush(adbd_fp); close_backup_fds(); - return 0; + return true; } bool twrpback::restore(void) { @@ -450,16 +507,15 @@ bool twrpback::restore(void) { struct AdbBackupControlType structcmd; int errctr = 0; uint64_t totalbytes = 0, dataChunkBytes = 0; - uint64_t md5fnsize = 0; + uint64_t md5fnsize = 0, fileBytes = 0; bool writedata, read_from_adb; - bool breakloop, eofsent, md5trsent; - bool compressed; - bool md5TrailerReceived = false; + bool eofsent, md5trsent, md5sumdata; + bool compressed, tweofrcvd, extraData; - breakloop = false; read_from_adb = true; signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); adbd_fp = fdopen(adbd_fd, "r"); if (adbd_fp == NULL) { @@ -481,7 +537,8 @@ bool twrpback::restore(void) { write_fd = open(TW_ADB_FIFO, O_WRONLY); errctr++; if (errctr > ADB_BU_MAX_ERROR) { - adblogwrite("Unable to open TW_ADB_FIFO\n"); + std::string msg = "Unable to open TW_ADB_FIFO."; + printErrMsg(msg, errno); close_restore_fds(); return false; } @@ -501,9 +558,8 @@ bool twrpback::restore(void) { adblogwrite("opening TW_ADB_BU_CONTROL\n"); adb_control_bu_fd = open(TW_ADB_BU_CONTROL, O_RDONLY | O_NONBLOCK); if (adb_control_bu_fd < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Unable to open TW_ADB_BU_CONTROL for writing. " + str.str() + "\n"); + std::string msg = "Unable to open TW_ADB_BU_CONTROL for writing."; + printErrMsg(msg, errno); close_restore_fds(); return false; } @@ -511,9 +567,8 @@ bool twrpback::restore(void) { adblogwrite("opening TW_ADB_TWRP_CONTROL\n"); adb_control_twrp_fd = open(TW_ADB_TWRP_CONTROL, O_WRONLY | O_NONBLOCK); if (adb_control_twrp_fd < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Unable to open TW_ADB_TWRP_CONTROL for writing. " + str.str() + ". Retrying...\n"); + std::string msg = "Unable to open TW_ADB_TWRP_CONTROL for writing. Retrying..."; + printErrMsg(msg, errno); while (adb_control_twrp_fd < 0) { adb_control_twrp_fd = open(TW_ADB_TWRP_CONTROL, O_WRONLY | O_NONBLOCK); usleep(10000); @@ -527,7 +582,7 @@ bool twrpback::restore(void) { } //Loop until we receive TWENDADB from TWRP - while (!breakloop) { + while (true) { memset(&cmd, 0, sizeof(cmd)); if (read(adb_control_bu_fd, &cmd, sizeof(cmd)) > 0) { struct AdbBackupControlType structcmd; @@ -537,17 +592,14 @@ bool twrpback::restore(void) { //If we receive TWEOF from TWRP close adb data fifo if (cmdtype == TWEOF) { adblogwrite("Received TWEOF\n"); - struct AdbBackupControlType tweof; - - memset(&tweof, 0, sizeof(tweof)); - memcpy(&tweof, readAdbStream, sizeof(readAdbStream)); read_from_adb = true; + tweofrcvd = true; + close(adb_write_fd); } //Break when TWRP sends TWENDADB else if (cmdtype == TWENDADB) { adblogwrite("Received TWENDADB\n"); - breakloop = true; - close_restore_fds(); + break; } //we received an error, exit and unlink else if (cmdtype == TWERROR) { @@ -568,6 +620,7 @@ bool twrpback::restore(void) { struct AdbBackupControlType endadb; uint32_t crc, endadbcrc; + md5sumdata = false; memset(&endadb, 0, sizeof(endadb)); memcpy(&endadb, readAdbStream, sizeof(readAdbStream)); endadbcrc = endadb.crc; @@ -576,11 +629,10 @@ bool twrpback::restore(void) { crc = crc32(crc, (const unsigned char*) &endadb, sizeof(endadb)); if (crc == endadbcrc) { - adblogwrite("Sending TWENDADB\n"); + adblogwrite("sending TWENDADB\n"); if (write(adb_control_twrp_fd, &endadb, sizeof(endadb)) < 1) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to ADB_CONTROL_READ_FD: " + str.str() + "\n"); + std::string msg = "Cannot write to ADB_CONTROL_READ_FD: "; + printErrMsg(msg, errno); close_restore_fds(); return false; } @@ -599,6 +651,7 @@ bool twrpback::restore(void) { ADBSTRUCT_STATIC_ASSERT(sizeof(cnthdr) == MAX_ADB_READ); + md5sumdata = false; memset(&cnthdr, 0, sizeof(cnthdr)); memcpy(&cnthdr, readAdbStream, sizeof(readAdbStream)); cnthdrcrc = cnthdr.crc; @@ -609,9 +662,8 @@ bool twrpback::restore(void) { if (crc == cnthdrcrc) { adblogwrite("Restoring TWSTREAMHDR\n"); if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); + std::string msg = "Cannot write to adb_control_twrp_fd: "; + printErrMsg(msg, errno); close_restore_fds(); return false; } @@ -626,6 +678,11 @@ bool twrpback::restore(void) { else if (cmdtype == TWIMG) { struct twfilehdr twimghdr; uint32_t crc, twimghdrcrc; + md5sumdata = false; + fileBytes = 0; + read_from_adb = true; + dataChunkBytes = 0; + extraData = false; digest.init(); adblogwrite("Restoring TWIMG\n"); @@ -639,9 +696,8 @@ bool twrpback::restore(void) { crc = crc32(crc, (const unsigned char*) &twimghdr, sizeof(twimghdr)); if (crc == twimghdrcrc) { if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); + std::string msg = "Cannot write to adb_control_twrp_fd: "; + printErrMsg(msg, errno); close_restore_fds(); return false; } @@ -651,6 +707,16 @@ bool twrpback::restore(void) { close_restore_fds(); return false; } + + #ifdef _DEBUG_ADB_BACKUP + std::string debug_fname = "/data/media/"; + debug_fname.append(basename(twimghdr.name)); + debug_fname.append("-restore.img"); + adblogwrite("image: " + debug_fname + "\n"); + debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666); + adblogwrite("Opened restore image\n"); + #endif + adblogwrite("opening TW_ADB_RESTORE\n"); adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY); } @@ -658,6 +724,11 @@ bool twrpback::restore(void) { else if (cmdtype == TWFN) { struct twfilehdr twfilehdr; uint32_t crc, twfilehdrcrc; + fileBytes = 0; + md5sumdata = false; + read_from_adb = true; + dataChunkBytes = 0; + extraData = false; digest.init(); adblogwrite("Restoring TWFN\n"); @@ -672,9 +743,8 @@ bool twrpback::restore(void) { if (crc == twfilehdrcrc) { if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); + std::string msg = "Cannot write to adb_control_twrp_fd: "; + printErrMsg(msg, errno); close_restore_fds(); return false; } @@ -685,75 +755,104 @@ bool twrpback::restore(void) { return false; } + #ifdef _DEBUG_ADB_BACKUP + std::string debug_fname = "/data/media/"; + debug_fname.append(basename(twfilehdr.name)); + debug_fname.append("-restore.tar"); + adblogwrite("tar: " + debug_fname + "\n"); + debug_adb_fd = open(debug_fname.c_str(), O_WRONLY | O_CREAT, 0666); + adblogwrite("Opened restore tar\n"); + #endif + + compressed = twfilehdr.compressed == 1 ? true: false; adblogwrite("opening TW_ADB_RESTORE\n"); adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY); } else if (cmdtype == MD5TRAILER) { - read_from_adb = false; //don't read from adb until TWRP sends TWEOF - close(adb_write_fd); - md5TrailerReceived = true; + if (fileBytes >= md5fnsize) + close(adb_write_fd); + if (tweofrcvd) { + read_from_adb = true; + tweofrcvd = false; + } + else + read_from_adb = false; //don't read from adb until TWRP sends TWEOF + md5sumdata = false; if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) { close_restore_fds(); - return false; + break; } + continue; } //Send the tar or partition image md5 to TWRP else if (cmdtype == TWDATA) { dataChunkBytes += sizeof(readAdbStream); - while (1) { + while (true) { if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) != sizeof(readAdbStream)) { close_restore_fds(); return false; } - memcpy(&structcmd, readAdbStream, sizeof(readAdbStream)); - - char *readAdbReadStream = new char [readbytes]; - memcpy(readAdbReadStream, readAdbStream, readbytes); std::string cmdtype = structcmd.get_type(); + dataChunkBytes += readbytes; - delete [] readAdbReadStream; totalbytes += readbytes; - digest.update((unsigned char*)readAdbReadStream, readbytes); + fileBytes += readbytes; if (cmdtype == MD5TRAILER) { - read_from_adb = false; //don't read from adb until TWRP sends TWEOF - close(adb_write_fd); + if (fileBytes >= md5fnsize) + close(adb_write_fd); + if (tweofrcvd) { + tweofrcvd = false; + read_from_adb = true; + } + else + read_from_adb = false; //don't read from adb until TWRP sends TWEOF if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) { close_restore_fds(); - return false; + break; } break; } + digest.update((unsigned char*)readAdbStream, readbytes); + + read_from_adb = true; + + #ifdef _DEBUG_ADB_BACKUP + if (write(debug_adb_fd, readAdbStream, sizeof(readAdbStream)) < 0) { + std::string msg = "Cannot write to ADB_CONTROL_READ_FD: "; + printErrMsg(msg, errno); + close_restore_fds(); + return false; + } + #endif if (write(adb_write_fd, readAdbStream, sizeof(readAdbStream)) < 0) { - adblogwrite("end of stream reached.\n"); + std::string msg = "Cannot write to TWRP ADB FIFO: "; + md5sumdata = true; + printErrMsg(msg, errno); + adblogwrite("end of stream reached.\n"); break; } + if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) { dataChunkBytes = 0; + md5sumdata = false; break; } - memset(&readAdbStream, 0, sizeof(readAdbStream)); } } - else { - if (!md5TrailerReceived) { - char *readAdbReadStream = new char [readbytes]; - memcpy(readAdbReadStream, readAdbStream, readbytes); - digest.update((unsigned char*)readAdbReadStream, readbytes); - totalbytes += readbytes; - delete [] readAdbReadStream; - } - + else if (md5sumdata) { + digest.update((unsigned char*)readAdbStream, sizeof(readAdbStream)); + md5sumdata = true; } } } } - std::stringstream str; str << totalbytes; + close_restore_fds(); adblogwrite(str.str() + " bytes restored from adbbackup\n"); return true; } @@ -786,7 +885,6 @@ bool twrpback::checkMD5Trailer(char readAdbStream[], uint64_t md5fnsize, twrpMD5 uint32_t crc, md5trcrc, md5ident, md5identmatch; ADBSTRUCT_STATIC_ASSERT(sizeof(md5tr) == MAX_ADB_READ); - memset(&md5tr, 0, sizeof(md5tr)); memcpy(&md5tr, readAdbStream, MAX_ADB_READ); md5ident = md5tr.ident; @@ -804,9 +902,8 @@ bool twrpback::checkMD5Trailer(char readAdbStream[], uint64_t md5fnsize, twrpMD5 crc = crc32(crc, (const unsigned char*) &md5tr, sizeof(md5tr)); if (crc == md5trcrc) { if (write(adb_control_twrp_fd, &md5tr, sizeof(md5tr)) < 1) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); + std::string msg = "Cannot write to adb_control_twrp_fd: "; + printErrMsg(msg, errno); close_restore_fds(); return false; } @@ -825,13 +922,10 @@ bool twrpback::checkMD5Trailer(char readAdbStream[], uint64_t md5fnsize, twrpMD5 std::string md5string = digest->return_digest_string(); strncpy(md5.md5, md5string.c_str(), sizeof(md5.md5)); - adblogwrite("sending MD5 verification\n"); - std::stringstream dstr; - dstr << adb_control_twrp_fd; + adblogwrite("sending MD5 verification: " + md5string + "\n"); if (write(adb_control_twrp_fd, &md5, sizeof(md5)) < 1) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); + std::string msg = "Cannot write to adb_control_twrp_fd: "; + printErrMsg(msg, errno); close_restore_fds(); return false; } diff --git a/adbbu/twrpback.hpp b/adbbu/twrpback.hpp index c52da3ea7..edc162651 100644 --- a/adbbu/twrpback.hpp +++ b/adbbu/twrpback.hpp @@ -42,6 +42,7 @@ private: int adb_control_bu_fd; // fd for twrp to bu communication int adb_read_fd; // adb read data stream int adb_write_fd; // adb write data stream + int debug_adb_fd; // fd to write debug tars bool firstPart; // first partition in the stream FILE *adbd_fp; // file pointer for adb stream char cmd[512]; // store result of commands @@ -54,6 +55,7 @@ private: void close_backup_fds(); // close backup resources void close_restore_fds(); // close restore resources bool checkMD5Trailer(char adbReadStream[], uint64_t md5fnsize, twrpMD5* digest); // Check MD5 Trailer + void printErrMsg(std::string msg, int errNum); // print error msg to adb log }; #endif // _TWRPBACK_HPP diff --git a/partition.cpp b/partition.cpp index 59bd16831..0272708cd 100644 --- a/partition.cpp +++ b/partition.cpp @@ -2414,8 +2414,9 @@ bool TWPartition::Raw_Read_Write(PartitionSettings *part_settings) { srcfn = Actual_Block_Device; if (part_settings->adbbackup) destfn = TW_ADB_BACKUP; - else + else { destfn = part_settings->Backup_Folder + "/" + Backup_FileName; + } } else { destfn = Actual_Block_Device; diff --git a/twrpAdbBuFifo.cpp b/twrpAdbBuFifo.cpp index 0c7dd1524..1147d63db 100644 --- a/twrpAdbBuFifo.cpp +++ b/twrpAdbBuFifo.cpp @@ -103,6 +103,8 @@ bool twrpAdbBuFifo::Backup_ADB_Command(std::string Options) { if (args[1].compare("--twrp") != 0) { gui_err("twrp_adbbu_option=--twrp option is required to enable twrp adb backup"); + if (!twadbbu::Write_TWERROR()) + LOGERR("Unable to write to ADB Backup\n"); sleep(2); return false; } @@ -130,9 +132,11 @@ bool twrpAdbBuFifo::Backup_ADB_Command(std::string Options) { } else { gui_msg(Msg(msg::kError, "partition_not_found=path: {1} not found in partition list")(path)); - return false; - } + if (!twadbbu::Write_TWERROR()) + LOGERR("Unable to write to TWRP ADB Backup.\n"); + return false; } +} if (Backup_List.empty()) { DataManager::GetValue("tw_backup_list", Backup_List); @@ -187,7 +191,7 @@ bool twrpAdbBuFifo::Restore_ADB_Backup(void) { DataManager::SetValue("tw_action_text2", ""); gui_changePage("action_page"); - while (1) { + while (true) { memset(&cmd, 0, sizeof(cmd)); if (read(adb_control_twrp_fd, cmd, sizeof(cmd)) > 0) { struct AdbBackupControlType cmdstruct; @@ -202,37 +206,49 @@ bool twrpAdbBuFifo::Restore_ADB_Backup(void) { LOGINFO("ADB version: %" PRIu64 "\n", twhdr.version); if (twhdr.version != ADB_BACKUP_VERSION) { LOGERR("Incompatible adb backup version!\n"); + ret = false; break; } partition_count = twhdr.partition_count; } else if (cmdtype == MD5TRAILER) { - LOGINFO("Restoring MD5TRAILER\n"); + LOGINFO("Reading ADB Backup MD5TRAILER\n"); memcpy(&adbmd5, cmd, sizeof(cmd)); } else if (cmdtype == TWMD5) { - struct AdbBackupFileTrailer md5check; - LOGINFO("Restoring TWMD5\n"); - - memset(&md5check, 0, sizeof(md5check)); - memcpy(&md5check, cmd, sizeof(cmd)); - if (strcmp(md5check.md5, adbmd5.md5) != 0) { - LOGERR("md5 doesn't match!\n"); - LOGERR("file md5: %s\n", adbmd5.md5); - LOGERR("check md5: %s\n", md5check.md5); - ret = false; - break; - } - else { - LOGINFO("adbrestore md5 matches\n"); - LOGINFO("adbmd5.md5: %s\n", adbmd5.md5); - LOGINFO("md5check.md5: %s\n", md5check.md5); - ret = true; - break; + int check_digest; + + DataManager::GetValue(TW_SKIP_DIGEST_CHECK_VAR, check_digest); + if (check_digest > 0) { + TWFunc::GUI_Operation_Text(TW_VERIFY_DIGEST_TEXT, gui_parse_text("{@verifying_digest}")); + gui_msg("verifying_digest=Verifying Digest"); + struct AdbBackupFileTrailer md5check; + LOGINFO("Verifying md5sums\n"); + + memset(&md5check, 0, sizeof(md5check)); + memcpy(&md5check, cmd, sizeof(cmd)); + if (strcmp(md5check.md5, adbmd5.md5) != 0) { + LOGERR("md5 doesn't match!\n"); + LOGERR("Stored file md5: %s\n", adbmd5.md5); + LOGERR("ADB Backup check md5: %s\n", md5check.md5); + ret = false; + break; + } + else { + LOGINFO("ADB Backup md5 matches\n"); + LOGINFO("Stored file md5: %s\n", adbmd5.md5); + LOGINFO("ADB Backup check md5: %s\n", md5check.md5); + continue; + } + } else { + gui_msg("skip_digest=Skipping Digest check based on user setting."); + continue; } + } else if (cmdtype == TWENDADB) { LOGINFO("received TWENDADB\n"); + ret = 1; break; } else { @@ -270,6 +286,7 @@ bool twrpAdbBuFifo::Restore_ADB_Backup(void) { if (!PartitionManager.Restore_Partition(&part_settings)) { LOGERR("ADB Restore failed.\n"); ret = false; + break; } } else if (cmdtype == TWFN) { @@ -296,17 +313,11 @@ bool twrpAdbBuFifo::Restore_ADB_Backup(void) { if (path.compare("/system") == 0) { if (part_settings.Part->Is_Read_Only()) { - struct AdbBackupControlType twerror; - strncpy(twerror.start_of_header, TWRP, sizeof(twerror.start_of_header)); - strncpy(twerror.type, TWERROR, sizeof(twerror.type)); - memset(twerror.space, 0, sizeof(twerror.space)); - twerror.crc = crc32(0L, Z_NULL, 0); - twerror.crc = crc32(twerror.crc, (const unsigned char*) &twerror, sizeof(twerror)); - if (write(adb_control_bu_fd, &twerror, sizeof(twerror)) < 0) { - LOGERR("Cannot write to ADB_CONTROL_BU_FD: %s\n", strerror(errno)); - } + if (!twadbbu::Write_TWERROR()) + LOGERR("Unable to write to TWRP ADB Backup.\n"); gui_msg(Msg(msg::kError, "restore_read_only=Cannot restore {1} -- mounted read only.")(part_settings.Part->Backup_Display_Name)); - return false; + ret = false; + break; } } @@ -320,6 +331,7 @@ bool twrpAdbBuFifo::Restore_ADB_Backup(void) { if (!PartitionManager.Restore_Partition(&part_settings)) { LOGERR("ADB Restore failed.\n"); ret = false; + break; } } } @@ -337,6 +349,5 @@ bool twrpAdbBuFifo::Restore_ADB_Backup(void) { DataManager::SetValue("ui_progress", 100); gui_changePage("main"); close(adb_control_bu_fd); - close(adb_control_twrp_fd); return ret; } -- cgit v1.2.3