summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--partitionmanager.cpp23
-rw-r--r--twrp-functions.cpp35
-rw-r--r--twrp-functions.hpp1
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