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
This commit is contained in:
Ethan Yonker
2014-12-11 10:00:45 -06:00
parent ac21cb5ae3
commit 4b94cfd391
15 changed files with 179 additions and 9 deletions

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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());

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -26,6 +26,7 @@
#include <sys/stat.h>
#include <dirent.h>
#include "../twcommon.h"
#include "../set_metadata.h"
#include <cutils/properties.h>
#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);

View File

@@ -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());

View File

@@ -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;
}

89
set_metadata.c Normal file
View File

@@ -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 <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#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;
}

45
set_metadata.h Normal file
View File

@@ -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 <sys/stat.h>
#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

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -21,6 +21,7 @@ extern "C" {
#include "libtar/libtar.h"
#include "twrpTar.h"
#include "tarWrite.h"
#include "set_metadata.h"
}
#include <sys/types.h>
#include <sys/stat.h>
@@ -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;
}