diff options
Diffstat (limited to '')
-rw-r--r-- | partitionmanager.cpp | 23 | ||||
-rw-r--r-- | twrp-functions.cpp | 35 | ||||
-rw-r--r-- | twrp-functions.hpp | 1 |
3 files changed, 56 insertions, 3 deletions
diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 908730e57..c1b857ca9 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -1513,7 +1513,7 @@ void TWPartitionManager::Post_Decrypt(const string& Block_Device) { int TWPartitionManager::Decrypt_Device(string Password) { #ifdef TW_INCLUDE_CRYPTO - char crypto_state[PROPERTY_VALUE_MAX], crypto_blkdev[PROPERTY_VALUE_MAX], cPassword[255]; + char crypto_state[PROPERTY_VALUE_MAX], crypto_blkdev[PROPERTY_VALUE_MAX]; std::vector<TWPartition*>::iterator iter; // Mount any partitions that need to be mounted for decrypt @@ -1549,8 +1549,25 @@ int TWPartitionManager::Decrypt_Device(string Password) { return -1; } - strcpy(cPassword, Password.c_str()); - int pwret = cryptfs_check_passwd(cPassword); + int pwret = -1; + pid_t pid = fork(); + if (pid < 0) { + LOGERR("fork failed\n"); + return -1; + } else if (pid == 0) { + // Child process + char cPassword[255]; + strcpy(cPassword, Password.c_str()); + int ret = cryptfs_check_passwd(cPassword); + exit(ret); + } else { + // Parent + int status; + if (TWFunc::Wait_For_Child_Timeout(pid, &status, "Decrypt", 30)) + pwret = -1; + else + pwret = WEXITSTATUS(status) ? -1 : 0; + } // Unmount any partitions that were needed for decrypt for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { diff --git a/twrp-functions.cpp b/twrp-functions.cpp index 3c6c55bce..c9643570f 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -142,6 +142,41 @@ int TWFunc::Wait_For_Child(pid_t pid, int *status, string Child_Name) { return 0; } +int TWFunc::Wait_For_Child_Timeout(pid_t pid, int *status, const string& Child_Name, int timeout) { + pid_t retpid = waitpid(pid, status, WNOHANG); + for (; retpid == 0 && timeout; --timeout) { + sleep(1); + retpid = waitpid(pid, status, WNOHANG); + } + if (retpid == 0 && timeout == 0) { + LOGERR("%s took too long, killing process\n", Child_Name.c_str()); + kill(pid, SIGKILL); + int died = 0; + for (timeout = 5; retpid == 0 && timeout; --timeout) { + sleep(1); + retpid = waitpid(pid, status, WNOHANG); + } + if (retpid) + LOGINFO("Child process killed successfully\n"); + else + LOGINFO("Child process took too long to kill, may be a zombie process\n"); + return -1; + } else if (retpid > 0) { + if (WIFSIGNALED(*status)) { + gui_msg(Msg(msg::kError, "pid_signal={1} process ended with signal: {2}")(Child_Name)(WTERMSIG(*status))); // Seg fault or some other non-graceful termination + return -1; + } + } else if (retpid < 0) { // no PID returned + if (errno == ECHILD) + LOGERR("%s no child process exist\n", Child_Name.c_str()); + else { + LOGERR("%s Unexpected error %d\n", Child_Name.c_str(), errno); + return -1; + } + } + return 0; +} + bool TWFunc::Path_Exists(string Path) { // Check to see if the Path exists struct stat st; diff --git a/twrp-functions.hpp b/twrp-functions.hpp index ebbe99d10..82a4c1b08 100644 --- a/twrp-functions.hpp +++ b/twrp-functions.hpp @@ -52,6 +52,7 @@ public: static int Exec_Cmd(const string& cmd, string &result); //execute a command and return the result as a string by reference static int Exec_Cmd(const string& cmd); //execute a command static int Wait_For_Child(pid_t pid, int *status, string Child_Name); // Waits for pid to exit and checks exit status + static int Wait_For_Child_Timeout(pid_t pid, int *status, const string& Child_Name, int timeout); // Waits for a pid to exit until the timeout is hit. If timeout is hit, kill the chilld. static bool Path_Exists(string Path); // Returns true if the path exists static Archive_Type Get_File_Type(string fn); // Determines file type, 0 for unknown, 1 for gzip, 2 for OAES encrypted static int Try_Decrypting_File(string fn, string password); // -1 for some error, 0 for failed to decrypt, 1 for decrypted, 3 for decrypted and found gzip format |