diff options
Diffstat (limited to 'twrp-functions.cpp')
-rwxr-xr-x[-rw-r--r--] | twrp-functions.cpp | 105 |
1 files changed, 82 insertions, 23 deletions
diff --git a/twrp-functions.cpp b/twrp-functions.cpp index 00a57a749..37dd0df48 100644..100755 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -37,6 +37,7 @@ #include <sstream> #include <cctype> #include <algorithm> +#include <selinux/label.h> #include "twrp-functions.hpp" #include "twcommon.h" #include "gui/gui.hpp" @@ -58,6 +59,8 @@ extern "C" { #include "libcrecovery/common.h" } +struct selabel_handle *selinux_handle; + /* Execute a command */ int TWFunc::Exec_Cmd(const string& cmd, string &result) { FILE* exec; @@ -520,28 +523,29 @@ void TWFunc::Copy_Log(string Source, string Destination) { } void TWFunc::Update_Log_File(void) { - // Copy logs to cache so the system can find out what happened. - if (PartitionManager.Mount_By_Path("/cache", false)) { - if (!TWFunc::Path_Exists("/cache/recovery/.")) { - LOGINFO("Recreating /cache/recovery folder.\n"); - if (mkdir("/cache/recovery", S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP) != 0) - LOGINFO("Unable to create /cache/recovery folder.\n"); + std::string recoveryDir = get_cache_dir() + "recovery/"; + + if (get_cache_dir() == NON_AB_CACHE_DIR) { + if (!PartitionManager.Mount_By_Path(NON_AB_CACHE_DIR, false)) { + LOGINFO("Failed to mount %s for TWFunc::Update_Log_File\n", NON_AB_CACHE_DIR); } - Copy_Log(TMP_LOG_FILE, "/cache/recovery/log"); - copy_file("/cache/recovery/log", "/cache/recovery/last_log", 600); - chown("/cache/recovery/log", 1000, 1000); - chmod("/cache/recovery/log", 0600); - chmod("/cache/recovery/last_log", 0640); - } else if (PartitionManager.Mount_By_Path("/data", false) && TWFunc::Path_Exists("/data/cache/recovery/.")) { - Copy_Log(TMP_LOG_FILE, "/data/cache/recovery/log"); - copy_file("/data/cache/recovery/log", "/data/cache/recovery/last_log", 600); - chown("/data/cache/recovery/log", 1000, 1000); - chmod("/data/cache/recovery/log", 0600); - chmod("/data/cache/recovery/last_log", 0640); - } else { - LOGINFO("Failed to mount /cache or find /data/cache for TWFunc::Update_Log_File\n"); } + if (!TWFunc::Path_Exists(recoveryDir)) { + LOGINFO("Recreating %s folder.\n", recoveryDir.c_str()); + if (mkdir(recoveryDir.c_str(), S_IRWXU | S_IRWXG | S_IWGRP | S_IXGRP) != 0) { + LOGINFO("Unable to create %s folder.\n", recoveryDir.c_str()); + } + } + + std::string logCopy = recoveryDir + "log"; + std::string lastLogCopy = recoveryDir + "last_log"; + copy_file(logCopy, lastLogCopy, 600); + Copy_Log(TMP_LOG_FILE, logCopy); + chown(logCopy.c_str(), 1000, 1000); + chmod(logCopy.c_str(), 0600); + chmod(lastLogCopy.c_str(), 0640); + // Reset bootloader message TWPartition* Part = PartitionManager.Find_Partition_By_Path("/misc"); if (Part != NULL) { @@ -555,12 +559,13 @@ void TWFunc::Update_Log_File(void) { } } - if (PartitionManager.Mount_By_Path("/cache", false)) { - if (unlink("/cache/recovery/command") && errno != ENOENT) { - LOGINFO("Can't unlink %s\n", "/cache/recovery/command"); + if (get_cache_dir() == NON_AB_CACHE_DIR) { + if (PartitionManager.Mount_By_Path("/cache", false)) { + if (unlink("/cache/recovery/command") && errno != ENOENT) { + LOGINFO("Can't unlink %s\n", "/cache/recovery/command"); + } } } - sync(); } @@ -1154,4 +1159,58 @@ int TWFunc::stream_adb_backup(string &Restore_Name) { return -1; return ret; } + +std::string TWFunc::get_cache_dir() { + if (PartitionManager.Find_Partition_By_Path(NON_AB_CACHE_DIR) == NULL) { + return AB_CACHE_DIR; + } + else { + return NON_AB_CACHE_DIR; + } +} + +void TWFunc::check_selinux_support() { + if (TWFunc::Path_Exists("/prebuilt_file_contexts")) { + if (TWFunc::Path_Exists("/file_contexts")) { + printf("Renaming regular /file_contexts -> /file_contexts.bak\n"); + rename("/file_contexts", "/file_contexts.bak"); + } + printf("Moving /prebuilt_file_contexts -> /file_contexts\n"); + rename("/prebuilt_file_contexts", "/file_contexts"); + } + struct selinux_opt selinux_options[] = { + { SELABEL_OPT_PATH, "/file_contexts" } + }; + selinux_handle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1); + if (!selinux_handle) + printf("No file contexts for SELinux\n"); + else + printf("SELinux contexts loaded from /file_contexts\n"); + { // Check to ensure SELinux can be supported by the kernel + char *contexts = NULL; + std::string cacheDir = TWFunc::get_cache_dir(); + std::string se_context_check = cacheDir + "recovery/"; + int ret = 0; + + if (cacheDir == NON_AB_CACHE_DIR) { + PartitionManager.Mount_By_Path(NON_AB_CACHE_DIR, false); + } + if (TWFunc::Path_Exists(se_context_check)) { + ret = lgetfilecon(se_context_check.c_str(), &contexts); + if (ret > 0) { + lsetfilecon(se_context_check.c_str(), "test"); + lgetfilecon(se_context_check.c_str(), &contexts); + } else { + LOGINFO("Could not check %s SELinux contexts, using /sbin/teamwin instead which may be inaccurate.\n", se_context_check.c_str()); + lgetfilecon("/sbin/teamwin", &contexts); + } + } + if (ret < 0) { + gui_warn("no_kernel_selinux=Kernel does not have support for reading SELinux contexts."); + } else { + free(contexts); + gui_msg("full_selinux=Full SELinux support is present."); + } + } +} #endif // ndef BUILD_TWRPTAR_MAIN |