From 4b94cfd3910de26dbca64cf746a899cbc635158b Mon Sep 17 00:00:00 2001 From: Ethan Yonker Date: Thu, 11 Dec 2014 10:00:45 -0600 Subject: Attempt to set the proper uid/gid/contexts on new files and dirs Files and folders that we create during backups, copy log, or MTP operations often do not have the proper uid/gid/contexts assigned. We will attempt to read the proper contexts from the settings storage path and assign those same contexts to any files or dirs that we create. Change-Id: I769f9479854122b49b499de2175e6e2d026f8afd --- Android.mk | 4 +-- data.cpp | 2 ++ gui/Android.mk | 2 +- gui/action.cpp | 8 +++++ infomanager.cpp | 4 ++- mtp/Android.mk | 4 +-- mtp/MtpServer.cpp | 3 ++ partition.cpp | 3 ++ partitionmanager.cpp | 2 ++ set_metadata.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++ set_metadata.h | 45 ++++++++++++++++++++++++++ twrp-functions.cpp | 11 +++++-- twrp.cpp | 7 +++++ twrpDigest.cpp | 2 ++ twrpTar.cpp | 2 ++ 15 files changed, 179 insertions(+), 9 deletions(-) create mode 100644 set_metadata.c create mode 100644 set_metadata.h diff --git a/Android.mk b/Android.mk index e909baae3..2a108777f 100644 --- a/Android.mk +++ b/Android.mk @@ -449,8 +449,8 @@ include $(CLEAR_VARS) LOCAL_MODULE := libaosprecovery LOCAL_MODULE_TAGS := eng optional LOCAL_C_INCLUDES := $(LOCAL_PATH)/libmincrypt/includes -LOCAL_SRC_FILES := adb_install.cpp asn1_decoder.cpp bootloader.cpp mtdutils/mtdutils.c legacy_property_service.c verifier.cpp -LOCAL_SHARED_LIBRARIES += libc liblog libcutils libmtdutils libfusesideload libmincrypttwrp +LOCAL_SRC_FILES := adb_install.cpp asn1_decoder.cpp bootloader.cpp mtdutils/mtdutils.c legacy_property_service.c verifier.cpp set_metadata.c +LOCAL_SHARED_LIBRARIES += libc liblog libcutils libmtdutils libfusesideload libmincrypttwrp libselinux ifneq ($(BOARD_RECOVERY_BLDRMSG_OFFSET),) LOCAL_CFLAGS += -DBOARD_RECOVERY_BLDRMSG_OFFSET=$(BOARD_RECOVERY_BLDRMSG_OFFSET) diff --git a/data.cpp b/data.cpp index 0d05c3d59..88bc86ada 100644 --- a/data.cpp +++ b/data.cpp @@ -46,6 +46,7 @@ #include "gui/blanktimer.hpp" #endif #include "find_file.hpp" +#include "set_metadata.h" #ifdef TW_USE_MODEL_HARDWARE_ID_FOR_DEVICE_ID #include "cutils/properties.h" @@ -333,6 +334,7 @@ int DataManager::SaveValues() } } fclose(out); + tw_set_default_metadata(mBackingFile.c_str()); #endif // ifdef TW_OEM_BUILD return 0; } diff --git a/gui/Android.mk b/gui/Android.mk index 479bc76f9..d7a605e96 100644 --- a/gui/Android.mk +++ b/gui/Android.mk @@ -33,7 +33,7 @@ else LOCAL_SRC_FILES += hardwarekeyboard.cpp endif -LOCAL_SHARED_LIBRARIES += libminuitwrp libc libstdc++ libminzip +LOCAL_SHARED_LIBRARIES += libminuitwrp libc libstdc++ libminzip libaosprecovery LOCAL_MODULE := libguitwrp # Use this flag to create a build that simulates threaded actions like installing zips, backups, restores, and wipes for theme testing diff --git a/gui/action.cpp b/gui/action.cpp index 6b8565aed..d72b33194 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -52,6 +52,7 @@ extern "C" { #include "cutils/properties.h" #include "../minadbd/adb.h" #include "../adb_install.h" +#include "../set_metadata.h" int TWinstall_zip(const char* path, int* wipe_cache); void run_script(const char *str1, const char *str2, const char *str3, const char *str4, const char *str5, const char *str6, const char *str7, int request_confirm); @@ -503,6 +504,7 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) PartitionManager.Mount_Current_Storage(true); dst = DataManager::GetCurrentStoragePath() + "/recovery.log"; TWFunc::copy_file("/tmp/recovery.log", dst.c_str(), 0755); + tw_set_default_metadata(dst.c_str()); sync(); gui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str()); } else @@ -1222,6 +1224,12 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */) int check = 0; std::string theme_path; + if (tw_get_default_metadata(DataManager::GetSettingsStoragePath().c_str()) != 0) { + LOGERR("Failed to get default contexts and file mode for storage files.\n"); + } else { + LOGINFO("Got default contexts and file mode for storage files.\n"); + } + theme_path = DataManager::GetSettingsStoragePath(); if (PartitionManager.Mount_By_Path(theme_path.c_str(), 1) < 0) { LOGERR("Unable to mount %s during reload function startup.\n", theme_path.c_str()); diff --git a/infomanager.cpp b/infomanager.cpp index 080fe1d28..864c431a5 100644 --- a/infomanager.cpp +++ b/infomanager.cpp @@ -39,6 +39,7 @@ #include "infomanager.hpp" #include "twcommon.h" #include "partitions.hpp" +#include "set_metadata.h" using namespace std; @@ -97,7 +98,7 @@ int InfoManager::SaveValues(void) { return -1; PartitionManager.Mount_By_Path(File, true); -LOGINFO("InfoManager saving '%s'\n", File.c_str()); + LOGINFO("InfoManager saving '%s'\n", File.c_str()); FILE* out = fopen(File.c_str(), "wb"); if (!out) return -1; @@ -112,6 +113,7 @@ LOGINFO("InfoManager saving '%s'\n", File.c_str()); fwrite(iter->second.c_str(), 1, length, out); } fclose(out); + tw_set_default_metadata(File.c_str()); return 0; } diff --git a/mtp/Android.mk b/mtp/Android.mk index 809a29aba..283a283dd 100755 --- a/mtp/Android.mk +++ b/mtp/Android.mk @@ -29,7 +29,7 @@ LOCAL_SRC_FILES = \ twrpMtp.cpp \ mtp_MtpDatabase.cpp \ node.cpp -LOCAL_SHARED_LIBRARIES += libz libc libusbhost libstdc++ libstlport libdl libcutils libutils +LOCAL_SHARED_LIBRARIES += libz libc libusbhost libstdc++ libstlport libdl libcutils libutils libaosprecovery ifneq ($(TW_MTP_DEVICE),) LOCAL_CFLAGS += -DUSB_MTP_DEVICE=$(TW_MTP_DEVICE) @@ -66,5 +66,5 @@ LOCAL_SRC_FILES = \ twrpMtp.cpp \ mtp_MtpDatabase.cpp \ node.cpp -LOCAL_SHARED_LIBRARIES += libz libc libusbhost libstdc++ libstlport libdl libcutils libutils +LOCAL_SHARED_LIBRARIES += libz libc libusbhost libstdc++ libstlport libdl libcutils libutils libaosprecovery include $(BUILD_EXECUTABLE) diff --git a/mtp/MtpServer.cpp b/mtp/MtpServer.cpp index 66a641404..f4af2b948 100755 --- a/mtp/MtpServer.cpp +++ b/mtp/MtpServer.cpp @@ -26,6 +26,7 @@ #include #include #include "../twcommon.h" +#include "../set_metadata.h" #include #include "MtpTypes.h" @@ -1002,6 +1003,7 @@ MtpResponseCode MtpServer::doSendObjectInfo() { return MTP_RESPONSE_GENERAL_ERROR; } chown((const char *)path, getuid(), mFileGroup); + tw_set_default_metadata((const char *)path); // SendObject does not get sent for directories, so call endSendObject here instead mDatabase->lockMutex(); @@ -1073,6 +1075,7 @@ MtpResponseCode MtpServer::doSendObject() { ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr); } close(mfr.fd); + tw_set_default_metadata((const char *)mSendObjectFilePath); if (ret < 0) { unlink(mSendObjectFilePath); diff --git a/partition.cpp b/partition.cpp index d84e48fae..b3c436f8b 100644 --- a/partition.cpp +++ b/partition.cpp @@ -42,6 +42,7 @@ #include "twrpDU.hpp" #include "fixPermissions.hpp" #include "infomanager.hpp" +#include "set_metadata.h" extern "C" { #include "mtdutils/mtdutils.h" #include "mtdutils/mounts.h" @@ -1748,6 +1749,7 @@ bool TWPartition::Backup_DD(string backup_folder) { Command = "dd if=" + Actual_Block_Device + " of='" + Full_FileName + "'" + " bs=" + DD_BS + " count=1"; LOGINFO("Backup command: '%s'\n", Command.c_str()); TWFunc::Exec_Cmd(Command); + tw_set_default_metadata(Full_FileName.c_str()); if (TWFunc::Get_File_Size(Full_FileName) == 0) { LOGERR("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str()); return false; @@ -1771,6 +1773,7 @@ bool TWPartition::Backup_Dump_Image(string backup_folder) { Command = "dump_image " + MTD_Name + " '" + Full_FileName + "'"; LOGINFO("Backup command: '%s'\n", Command.c_str()); TWFunc::Exec_Cmd(Command); + tw_set_default_metadata(Full_FileName.c_str()); if (TWFunc::Get_File_Size(Full_FileName) == 0) { // Actual size may not match backup size due to bad blocks on MTD devices so just check for 0 bytes LOGERR("Backup file size for '%s' is 0 bytes.\n", Full_FileName.c_str()); diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 437ed2f33..92b287557 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -38,6 +38,7 @@ #include "fixPermissions.hpp" #include "twrpDigest.hpp" #include "twrpDU.hpp" +#include "set_metadata.h" #ifdef TW_HAS_MTP #include "mtp/mtp_MtpServer.hpp" @@ -757,6 +758,7 @@ int TWPartitionManager::Run_Backup(void) { gui_print_color("highlight", "[BACKUP COMPLETED IN %d SECONDS]\n\n", total_time); // the end string backup_log = Full_Backup_Path + "recovery.log"; TWFunc::copy_file("/tmp/recovery.log", backup_log, 0644); + tw_set_default_metadata(backup_log.c_str()); return true; } diff --git a/set_metadata.c b/set_metadata.c new file mode 100644 index 000000000..f4e0de24a --- /dev/null +++ b/set_metadata.c @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 The Team Win Recovery Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * The purpose of these functions is to try to get and set the proper + * file permissions, SELinux contexts, owner, and group so that these + * files are accessible when we boot up to normal Android via MTP and to + * file manager apps. During early boot we try to read the contexts and + * owner / group info from /data/media or from /data/media/0 and store + * them in static variables. From there, we'll try to set the same + * contexts, owner, and group information on most files we create during + * operations like backups, copying the log, and MTP operations. + */ + +#include +#include +#include +#include "selinux/selinux.h" + +static security_context_t selinux_context; +struct stat s; +static int has_stat = 0; + +int tw_get_context(const char* filename) { + if (lgetfilecon(filename, &selinux_context) >= 0) { + printf("tw_get_context got selinux context: %s\n", selinux_context); + return 0; + } else { + printf("tw_get_context failed to get selinux context"); + selinux_context = NULL; + } + return -1; +} + +int tw_get_stat(const char* filename) { + if (lstat(filename, &s) == 0) { + has_stat = 1; + return 0; + } + printf("tw_get_stat failed to lstat '%s'\n", filename); + return -1; +} + +int tw_get_default_metadata(const char* filename) { + if (tw_get_context(filename) == 0 && tw_get_stat(filename) == 0) + return 0; + return -1; +} + +// Most of this logging is disabled to prevent log spam if we are trying +// to set contexts and permissions on file systems that do not support +// these types of things (e.g. vfat / FAT / FAT32). +int tw_set_default_metadata(const char* filename) { + int ret = 0; + struct stat st; + + if (selinux_context == NULL) { + //printf("selinux_context was null, '%s'\n", filename); + ret = -1; + } else if (lsetfilecon(filename, selinux_context) < 0) { + //printf("Failed to set default contexts on '%s'.\n", filename); + ret = -1; + } + + if (lstat(filename, &st) == 0 && st.st_mode & S_IFREG && chmod(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) < 0) { + //printf("Failed to chmod '%s'\n", filename); + ret = -1; + } + + if (has_stat && chown(filename, s.st_uid, s.st_gid) < 0) { + //printf("Failed to lchown '%s'.\n", filename); + ret = -1; + } + //printf("Done trying to set defaults on '%s'\n"); + return ret; +} diff --git a/set_metadata.h b/set_metadata.h new file mode 100644 index 000000000..835c31cd7 --- /dev/null +++ b/set_metadata.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 The Team Win Recovery Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * The purpose of these functions is to try to get and set the proper + * file permissions, SELinux contexts, owner, and group so that these + * files are accessible when we boot up to normal Android via MTP and to + * file manager apps. During early boot we try to read the contexts and + * owner / group info from /data/media or from /data/media/0 and store + * them in static variables. From there, we'll try to set the same + * contexts, owner, and group information on most files we create during + * operations like backups, copying the log, and MTP operations. + */ + +#ifndef _RECOVERY_SET_CONTEXTS_H +#define _RECOVERY_SET_CONTEXTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "selinux/selinux.h" + +int tw_get_default_metadata(const char* filename); +int tw_set_default_metadata(const char* filename); + +#ifdef __cplusplus +} +#endif + +#endif //_RECOVERY_SET_CONTEXTS_H diff --git a/twrp-functions.cpp b/twrp-functions.cpp index 96114241f..b51024cf1 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -54,6 +54,7 @@ extern "C" { #include "libcrecovery/common.h" + #include "set_metadata.h" } /* Execute a command */ @@ -406,9 +407,13 @@ int TWFunc::Recursive_Mkdir(string Path) { while (pos != string::npos) { wholePath = pathCpy.substr(0, pos); - if (mkdir(wholePath.c_str(), 0777) && errno != EEXIST) { - LOGERR("Unable to create folder: %s (errno=%d)\n", wholePath.c_str(), errno); - return false; + if (!TWFunc::Path_Exists(wholePath)) { + if (mkdir(wholePath.c_str(), 0777)) { + LOGERR("Unable to create folder: %s (errno=%d)\n", wholePath.c_str(), errno); + return false; + } else { + tw_set_default_metadata(wholePath.c_str()); + } } pos = pathCpy.find("/", pos + 1); diff --git a/twrp.cpp b/twrp.cpp index a633becfb..f76ab641d 100644 --- a/twrp.cpp +++ b/twrp.cpp @@ -35,6 +35,7 @@ extern "C" { extern "C" { #include "gui/gui.h" +#include "set_metadata.h" } #include "twcommon.h" #include "twrp-functions.hpp" @@ -274,6 +275,12 @@ int main(int argc, char **argv) { if (gui_startPage("decrypt") != 0) { LOGERR("Failed to start decrypt GUI page.\n"); } + } else if (datamedia) { + if (tw_get_default_metadata(DataManager::GetSettingsStoragePath().c_str()) != 0) { + LOGERR("Failed to get default contexts and file mode for storage files.\n"); + } else { + LOGINFO("Got default contexts and file mode for storage files.\n"); + } } // Read the settings file diff --git a/twrpDigest.cpp b/twrpDigest.cpp index 0693c5500..c3cff7194 100644 --- a/twrpDigest.cpp +++ b/twrpDigest.cpp @@ -40,6 +40,7 @@ extern "C" #include "variables.h" #include "twrp-functions.hpp" #include "twrpDigest.hpp" +#include "set_metadata.h" using namespace std; @@ -79,6 +80,7 @@ int twrpDigest::write_md5digest(void) { md5string += basename((char*) md5fn.c_str()); md5string += + "\n"; TWFunc::write_file(md5file, md5string); + tw_set_default_metadata(md5file.c_str()); LOGINFO("MD5 for %s: %s\n", md5fn.c_str(), md5string.c_str()); return 0; } diff --git a/twrpTar.cpp b/twrpTar.cpp index b5d66d31b..968b6b9e7 100644 --- a/twrpTar.cpp +++ b/twrpTar.cpp @@ -21,6 +21,7 @@ extern "C" { #include "libtar/libtar.h" #include "twrpTar.h" #include "tarWrite.h" + #include "set_metadata.h" } #include #include @@ -1242,6 +1243,7 @@ int twrpTar::closeTar() { LOGERR("Backup file size for '%s' is 0 bytes.\n", tarfn.c_str()); return -1; } + tw_set_default_metadata(tarfn.c_str()); return 0; } -- cgit v1.2.3