summaryrefslogtreecommitdiffstats
path: root/twrp-functions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'twrp-functions.cpp')
-rwxr-xr-x[-rw-r--r--]twrp-functions.cpp105
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