diff options
author | Dariusz Michaluk <d.michaluk@samsung.com> | 2019-05-29 16:35:21 +0200 |
---|---|---|
committer | Tomasz Swierczek <t.swierczek@samsung.com> | 2019-11-20 11:09:41 +0000 |
commit | 45c146d559b0dd7671f6a71a674433e7b1b591a3 (patch) | |
tree | 5222c6679086b47ae8294d2a7c93afa2ee0824d3 | |
parent | c8f208b7498a6c659386d316cf24ee3c9b275769 (diff) | |
download | security-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.cpp | 55 | ||||
-rw-r--r-- | src/common/include/mount-namespace.h | 3 | ||||
-rw-r--r-- | src/common/include/service_impl.h | 7 | ||||
-rw-r--r-- | src/common/mount-namespace.cpp | 28 | ||||
-rw-r--r-- | src/common/service_impl.cpp | 10 | ||||
-rw-r--r-- | src/server/service/include/service.h | 1 | ||||
-rw-r--r-- | src/server/service/service.cpp | 10 |
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) |