summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDariusz Michaluk <d.michaluk@samsung.com>2019-05-29 16:35:21 +0200
committerTomasz Swierczek <t.swierczek@samsung.com>2019-11-20 11:09:41 +0000
commit45c146d559b0dd7671f6a71a674433e7b1b591a3 (patch)
tree5222c6679086b47ae8294d2a7c93afa2ee0824d3
parentc8f208b7498a6c659386d316cf24ee3c9b275769 (diff)
downloadsecurity-manager-45c146d559b0dd7671f6a71a674433e7b1b591a3.tar.gz
security-manager-45c146d559b0dd7671f6a71a674433e7b1b591a3.tar.bz2
security-manager-45c146d559b0dd7671f6a71a674433e7b1b591a3.zip
Implement SharedRO with mount namespace
Perform three bind mounts to implement SharedRO policy. Change-Id: Ib30cf1537bdb1357ef53b77ead52a00b469566d1
-rw-r--r--src/client/client-security-manager.cpp55
-rw-r--r--src/common/include/mount-namespace.h3
-rw-r--r--src/common/include/service_impl.h7
-rw-r--r--src/common/mount-namespace.cpp28
-rw-r--r--src/common/service_impl.cpp10
-rw-r--r--src/server/service/include/service.h1
-rw-r--r--src/server/service/service.cpp10
7 files changed, 91 insertions, 23 deletions
diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp
index cc3d7bd6..13f4484b 100644
--- a/src/client/client-security-manager.cpp
+++ b/src/client/client-security-manager.cpp
@@ -62,6 +62,7 @@
#include <group2gid.h>
#include <config.h>
#include <config-file.h>
+#include <tzplatform-config.h>
#include <security-manager.h>
#include <client-offline.h>
@@ -797,13 +798,47 @@ int security_manager_drop_process_privileges(void)
return SECURITY_MANAGER_SUCCESS;
}
-static int setupMountNamespace(const std::string &appProcessLabel, std::vector<std::pair<std::string, bool>> &privilegeStatusVector)
+static int setupSharedRO(const std::string &pkg_name, bool enabledSharedRO)
+{
+ int ret;
+ std::string userAppsRWDir = TizenPlatformConfig::getEnv(TZ_USER_APP);
+ std::string userAppsRWSharedDir = userAppsRWDir + "/.shared/";
+ std::string userPkgAppsRWSharedDir = userAppsRWSharedDir + pkg_name + "/";
+ std::string userPkgAppsRWSharedTmpDir = userAppsRWDir + "/.shared_tmp/" + pkg_name + "/";
+
+ if (enabledSharedRO) {
+ if (FS::directoryStatus(userPkgAppsRWSharedDir) == 1 && FS::directoryStatus(userPkgAppsRWSharedTmpDir) == 1) {
+ ret = MountNS::bindMountRW(userPkgAppsRWSharedDir, userPkgAppsRWSharedTmpDir);
+ if (ret != SECURITY_MANAGER_SUCCESS)
+ return ret;
+ }
+ }
+
+ if (FS::directoryStatus(userAppsRWSharedDir) == 1) {
+ ret = MountNS::bindMountRO(userAppsRWSharedDir, userAppsRWSharedDir);
+ if (ret != SECURITY_MANAGER_SUCCESS)
+ return ret;
+ }
+
+ if (enabledSharedRO) {
+ if (FS::directoryStatus(userPkgAppsRWSharedDir) == 1 && FS::directoryStatus(userPkgAppsRWSharedTmpDir) == 1) {
+ ret = MountNS::bindMountRW(userPkgAppsRWSharedTmpDir, userPkgAppsRWSharedDir);
+ if (ret != SECURITY_MANAGER_SUCCESS)
+ return ret;
+ }
+ }
+
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+static int setupMountNamespace(const std::string &appName, const std::string &appProcessLabel,
+ std::vector<std::pair<std::string, bool>> &privilegeStatusVector, bool &enabledSharedRO, std::string &pkgName)
{
ClientRequest request(SecurityModuleCall::APP_SETUP_NAMESPACE);
- if (request.send(appProcessLabel).failed())
+ if (request.send(appName, appProcessLabel).failed())
return request.getStatus();
- request.recv(privilegeStatusVector);
+ request.recv(privilegeStatusVector, pkgName, enabledSharedRO);
return SECURITY_MANAGER_SUCCESS;
}
@@ -824,7 +859,7 @@ int security_manager_prepare_app_candidate(void)
});
}
-static inline int security_manager_setup_namespace_internal(const std::string &app_label)
+static inline int security_manager_setup_namespace_internal(const std::string &app_name, const std::string &app_label)
{
if (!MountNS::isMountNamespaceEnabled())
return SECURITY_MANAGER_SUCCESS;
@@ -834,12 +869,20 @@ static inline int security_manager_setup_namespace_internal(const std::string &a
return ret;
std::vector<std::pair<std::string, bool>> privilegeStatusVector;
- ret = setupMountNamespace(app_label, privilegeStatusVector);
+ bool enabledSharedRO;
+ std::string pkg_name;
+ ret = setupMountNamespace(app_name, app_label, privilegeStatusVector, enabledSharedRO, pkg_name);
if (ret != SECURITY_MANAGER_SUCCESS) {
LogError("Failed to setup app namespace: " << security_manager_strerror(static_cast<lib_retcode>(ret)));
return ret;
}
+ ret = setupSharedRO(pkg_name, enabledSharedRO);
+ if (ret != SECURITY_MANAGER_SUCCESS) {
+ LogError("Failed to setup app SharedRO: " << security_manager_strerror(static_cast<lib_retcode>(ret)));
+ return ret;
+ }
+
auto storagePrivilegePathMap = MountNS::getPrivilegePathMap(getuid());
for (auto &privilegeStatus : privilegeStatusVector) {
auto it = storagePrivilegePathMap.find(privilegeStatus.first);
@@ -886,7 +929,7 @@ int security_manager_prepare_app(const char *app_name)
return ret;
}
- ret = security_manager_setup_namespace_internal(app_label);
+ ret = security_manager_setup_namespace_internal(app_name, app_label);
if (ret != SECURITY_MANAGER_SUCCESS) {
LogError("Unable to setup namespace for application " << app_name);
return ret;
diff --git a/src/common/include/mount-namespace.h b/src/common/include/mount-namespace.h
index e3b517e9..6c649f09 100644
--- a/src/common/include/mount-namespace.h
+++ b/src/common/include/mount-namespace.h
@@ -55,7 +55,8 @@ int createMountNamespace(void);
bool enterMountNamespace(const Path &mntPath);
int makeMountSlave(const Path &mountPoint);
int makeMountPrivate(const Path &mountPoint);
-int bindMount(const Path &source, const Path &target);
+int bindMountRW(const Path &source, const Path &target);
+int bindMountRO(const Path &source, const Path &target);
int uMount(const Path &target);
bool isPathBound(const Path &what, const Path &where);
diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h
index c569f4ac..5aff16fc 100644
--- a/src/common/include/service_impl.h
+++ b/src/common/include/service_impl.h
@@ -322,13 +322,16 @@ public:
* Setup app namespace
*
* @param[in] creds credentials of the requesting process
+ * @param[in] appName application identifier
* @param[in] appProcessLabel application identifier
* @param[out] privilegeStatusVector returned vector of privilege-status pair
+ * @param[out] enabledSharedRO placeholder for check shared_ro result
+ * @param[out] pkgName application package name
*
* @return API return code, as defined in protocols.h
*/
- int appSetupNamespace(const Credentials &creds, const std::string &appProcessLabel,
- std::vector<std::pair<std::string, bool>> &privilegeStatusVector);
+ int appSetupNamespace(const Credentials &creds, const std::string &appName, const std::string &appProcessLabel,
+ std::vector<std::pair<std::string, bool>> &privilegeStatusVector, bool &enabledSharedRO, std::string &pkgName);
/**
diff --git a/src/common/mount-namespace.cpp b/src/common/mount-namespace.cpp
index 0eeada77..b1283724 100644
--- a/src/common/mount-namespace.cpp
+++ b/src/common/mount-namespace.cpp
@@ -100,7 +100,7 @@ int applyPrivilegePath(bool allow, const PrivilegePath &privilegePath)
return 0;
LogDebug("Bind mounting " << srcPath << " to " << privilegePath.dstPath);
- return bindMount(srcPath, privilegePath.dstPath);
+ return bindMountRW(srcPath, privilegePath.dstPath);
}
std::string getUsersAppsMountPointsPath(void)
@@ -135,11 +135,6 @@ bool isMountNamespaceEnabled(void)
return false;
if (st.st_size == 0)
return false;
-
- // File exists and is not empty.
- // Let's check if it contains any relevant configuration entries.
- if (getPrivilegePathMap(getuid()).empty())
- return false;
} catch (...) {
return false;
}
@@ -195,13 +190,30 @@ int makeMountPrivate(const Path &mountPoint)
return SECURITY_MANAGER_SUCCESS;
}
-int bindMount(const Path &source, const Path &target)
+int bindMountRW(const Path &source, const Path &target)
{
int ret = mount(source.c_str(), target.c_str(), NULL, MS_BIND, NULL);
if (ret != 0) {
- LogError("Failed to bind directory " << source << " to " << target << " " << GetErrnoString(errno));
+ LogError("Failed to RW bind directory " << source << " to " << target << " " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
+ }
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+int bindMountRO(const Path &source, const Path &target)
+{
+ int ret = mount(source.c_str(), target.c_str(), NULL, MS_BIND|MS_RDONLY, NULL);
+ if (ret != 0) {
+ LogError("Failed to RO bind directory " << source << " to " << target << " " << GetErrnoString(errno));
return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
}
+
+ ret = mount("none", target.c_str(), NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL);
+ if (ret != 0) {
+ LogError("Failed to RO bind directory " << source << " to " << target << " " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_MOUNT_ERROR;
+ }
+
return SECURITY_MANAGER_SUCCESS;
}
diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp
index 4ad92b91..de13790c 100644
--- a/src/common/service_impl.cpp
+++ b/src/common/service_impl.cpp
@@ -1966,8 +1966,8 @@ int ServiceImpl::getClientPrivilegeLicense(
return SECURITY_MANAGER_SUCCESS;
}
-int ServiceImpl::appSetupNamespace(const Credentials &creds, const std::string &appProcessLabel,
- std::vector<std::pair<std::string, bool>> &privilegeStatusVector)
+int ServiceImpl::appSetupNamespace(const Credentials &creds, const std::string &appName, const std::string &appProcessLabel,
+ std::vector<std::pair<std::string, bool>> &privilegeStatusVector, bool &enabledSharedRO, std::string &pkgName)
{
int ret;
if (!authenticate(creds, PRIVILEGE_APP_NAMESPACE)) {
@@ -2012,6 +2012,12 @@ int ServiceImpl::appSetupNamespace(const Credentials &creds, const std::string &
privilegeStatusVector.push_back(make_pair(it.first, result));
}
+ m_privilegeDb.GetAppPkgName(appName, pkgName);
+ enabledSharedRO = m_privilegeDb.IsPackageSharedRO(pkgName);
+
+ } catch (const PrivilegeDb::Exception::Base &e) {
+ LogError("Error while getting shared_ro flag from database: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
} catch (const CynaraException::Base &e) {
LogError("Error while querying Cynara for permissions: " << e.DumpToString());
return SECURITY_MANAGER_ERROR_SERVER_ERROR;
diff --git a/src/server/service/include/service.h b/src/server/service/include/service.h
index 1c697b05..3cb97d67 100644
--- a/src/server/service/include/service.h
+++ b/src/server/service/include/service.h
@@ -260,6 +260,7 @@ private:
* @param creds credentials of the requesting process
*/
void processAppCleanNamespace(MessageBuffer &buffer, MessageBuffer &send, const Credentials &creds);
+
};
} // namespace SecurityManager
diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp
index f233f201..7d4255c9 100644
--- a/src/server/service/service.cpp
+++ b/src/server/service/service.cpp
@@ -485,14 +485,16 @@ void Service::processGetClientPrivilegeLicense(MessageBuffer &buffer, MessageBuf
void Service::processAppSetupNamespace(MessageBuffer &buffer, MessageBuffer &send, const Credentials &creds)
{
- std::string appProcessLabel;
+ std::string appName, appProcessLabel;
std::vector<std::pair<std::string, bool>> privilegeStatusVector;
+ bool enabledSharedRO;
+ std::string pkgName;
- Deserialization::Deserialize(buffer, appProcessLabel);
- int ret = serviceImpl.appSetupNamespace(creds, appProcessLabel, privilegeStatusVector);
+ Deserialization::Deserialize(buffer, appName, appProcessLabel);
+ int ret = serviceImpl.appSetupNamespace(creds, appName, appProcessLabel, privilegeStatusVector, enabledSharedRO, pkgName);
Serialization::Serialize(send, ret);
if (ret == SECURITY_MANAGER_SUCCESS)
- Serialization::Serialize(send, privilegeStatusVector);
+ Serialization::Serialize(send, privilegeStatusVector, pkgName, static_cast<int>(enabledSharedRO));
}
void Service::processAppCleanNamespace(MessageBuffer &buffer, MessageBuffer &send, const Credentials &creds)