From: Konrad Lipinski Date: Mon, 18 Jul 2022 10:22:49 +0000 (+0200) Subject: Fix subsession paths X-Git-Tag: submit/tizen/20220719.015501~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F85%2F278285%2F3;p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git Fix subsession paths * place the "subsession" dir in TZ_USER_HOME instead of TZ_USER_APP * skip over the empty subsession as returned by sessiond * add sharedRO paths if applicable * refrain from labelling paths inside skelDir for local installations * refactor related code to reduce redundancy and improve robustness Change-Id: I2ede9f53f490c9bf57d390796e2ca5a1774f8a09 --- diff --git a/src/common/include/service_impl_utils.h b/src/common/include/service_impl_utils.h index a0247957..80d37169 100644 --- a/src/common/include/service_impl_utils.h +++ b/src/common/include/service_impl_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2019-2022 Samsung Electronics Co., Ltd. All rights reserved. * * This file is licensed under the terms of MIT License or the Apache License * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. @@ -41,12 +41,13 @@ std::string realPath(const std::string &path); bool containSubDir(const std::string &parent, const pkg_paths &paths); -bool getSkelPkgDir(const std::string &pkgSubDir, std::string &skelPkgDir); +std::string getSkelDir(); int getLegalPkgBaseDirs(const uid_t &uid, const std::string &pkgName, app_install_type installType, std::string &homePath, + std::string &skelDir, std::vector &legalPkgBaseDirs, bool isSharedRO); diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp index a7e15c09..1de360fe 100644 --- a/src/common/service_impl.cpp +++ b/src/common/service_impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2014-2022 Samsung Electronics Co., Ltd. All rights reserved. * * This file is licensed under the terms of MIT License or the Apache License * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. @@ -155,6 +155,16 @@ bool verifyAppDefinedPrivileges(app_inst_req &req) return true; } +void labelSharedPaths(const std::string &baseDir, const std::string &pkgName) +{ + const auto sharedPath = baseDir + ".shared/" + pkgName; + const auto sharedTmpPath = baseDir + ".shared_tmp/" + pkgName; + if (FS::directoryStatus(sharedPath) > 0 && FS::directoryStatus(sharedTmpPath) > 0) { + SmackLabels::setupPkgBasePath(sharedPath); + SmackLabels::setupPkgBasePath(sharedTmpPath); + } +} + } // end of anonymous namespace ServiceImpl::ServiceImpl(Offline offline) : @@ -350,10 +360,10 @@ int ServiceImpl::labelPaths(const pkg_paths &paths, std::string authorHash; m_privilegeDb.GetPkgAuthorHash(pkgName, authorHash); - std::string homePath; + std::string homePath, skelDir; std::vector pkgLegalBaseDirs; int ret = getLegalPkgBaseDirs(uid, pkgName, installationType, homePath, - pkgLegalBaseDirs, isSharedRO); + skelDir, pkgLegalBaseDirs, isSharedRO); if (ret != SECURITY_MANAGER_SUCCESS) { LogError("Failed to generate legal directories for application"); return ret; @@ -365,27 +375,10 @@ int ServiceImpl::labelPaths(const pkg_paths &paths, if (isSharedRO) { // Label shared_ro base paths for bind mounting - std::string sharedPath = homePath + ".shared/" + pkgName; - std::string sharedTmpPath = homePath + ".shared_tmp/" + pkgName; - if (FS::directoryStatus(sharedPath) == 1 && FS::directoryStatus(sharedTmpPath) == 1) { - SmackLabels::setupPkgBasePath(sharedPath); - SmackLabels::setupPkgBasePath(sharedTmpPath); - } + labelSharedPaths(homePath, pkgName); // If there are corresponding paths in skel, label them too - std::string skelSharedPath; - std::string skelSharedTmpPath; - if (!getSkelPkgDir(".shared/" + pkgName, skelSharedPath)) { - LogError("Couldn't generate skel shared RO path"); - return SECURITY_MANAGER_ERROR_UNKNOWN; - } - if (!getSkelPkgDir(".shared_tmp/" + pkgName, skelSharedTmpPath)) { - LogError("Couldn't generate skel shared RO path"); - return SECURITY_MANAGER_ERROR_UNKNOWN; - } - if (FS::directoryStatus(skelSharedPath) == 1 && FS::directoryStatus(skelSharedTmpPath) == 1) { - SmackLabels::setupPkgBasePath(skelSharedPath); - SmackLabels::setupPkgBasePath(skelSharedTmpPath); - } + if (!skelDir.empty()) + labelSharedPaths(skelDir, pkgName); } // register paths for (const auto &pkgPath : paths) { diff --git a/src/common/service_impl_utils.cpp b/src/common/service_impl_utils.cpp index 967a909c..14a7b422 100644 --- a/src/common/service_impl_utils.cpp +++ b/src/common/service_impl_utils.cpp @@ -60,35 +60,44 @@ bool isSubDir(const std::string &parent, const std::string &subdir) return (*str2 == '/' || *str1 == *str2); } -} // end of anonymous namespace - -static bool getPath(TizenPlatformConfig &tpc, enum tzplatform_variable id, const std::string &subDir, std::string &path) +std::string getDir(TizenPlatformConfig &tpc, enum tzplatform_variable id) { - path = realPath(tpc.ctxGetEnv(id)); - if (path.empty()) - return false; - - path += "/" + subDir; + auto dir = realPath(tpc.ctxGetEnv(id)); + if (!dir.empty()) + dir.push_back('/'); + return dir; +} - return true; +void addPkgDirs(std::vector &legalPkgDirs, const std::string &pkgName, + bool isSharedRO, const std::string &baseDir) +{ + legalPkgDirs.emplace_back(baseDir + pkgName); + if (isSharedRO) + legalPkgDirs.emplace_back(baseDir + ".shared/" + pkgName); } -bool getSkelPkgDir(const std::string &pkgSubDir, - std::string &skelPkgDir) +} // end of anonymous namespace + +std::string getSkelDir() { - std::string app = TizenPlatformConfig::getEnv(TZ_USER_APP); - std::string home = TizenPlatformConfig::getEnv(TZ_USER_HOME); - std::string real_skel_dir = std::move(realPath(SKEL_DIR)); - if (real_skel_dir.empty()) { - LogError("Unable to get skel pkg dir."); - return false; + const auto realSkel = realPath(SKEL_DIR); + if (realSkel.empty()) { + LogError("Unable to get skel dir."); + return {}; } - skelPkgDir.assign(app); - skelPkgDir.replace(0, home.length(), real_skel_dir); - skelPkgDir.append("/").append(pkgSubDir); + auto dir = TizenPlatformConfig::getEnv(TZ_USER_APP); + const auto home = TizenPlatformConfig::getEnv(TZ_USER_HOME); - return true; + if (dir.rfind(home, 0) != 0 || dir[home.size()] != '/') { + LogError("Dir (" << dir << ") does not start with home (" << home << ")"); + return {}; + } + + dir.replace(0, home.size(), realSkel); + dir.push_back('/'); + + return dir; } std::string realPath(const std::string &path) @@ -106,24 +115,22 @@ int getLegalPkgBaseDirs(const uid_t &uid, const std::string &pkgName, app_install_type installType, std::string &homePath, + std::string &skelDir, std::vector &legalPkgDirs, bool isSharedRO) { TizenPlatformConfig tpc(uid); - bool isSdAvailable = false; bool isSkelAvailable = false; enum tzplatform_variable baseId; enum tzplatform_variable extendedSdId = _TZPLATFORM_VARIABLES_INVALID_; switch (installType) { case SM_APP_INSTALL_LOCAL: - isSdAvailable = true; baseId = TZ_USER_APP; extendedSdId = TZ_USER_EXTENDEDSD_APP; break; case SM_APP_INSTALL_GLOBAL: - isSdAvailable = true; isSkelAvailable = true; baseId = TZ_SYS_RW_APP; extendedSdId = TZ_SYS_EXTENDEDSD_APP; @@ -139,65 +146,44 @@ int getLegalPkgBaseDirs(const uid_t &uid, legalPkgDirs.clear(); - if (!getPath(tpc, baseId, "", homePath)) { - LogError("Couldn't generate home path"); + if ((homePath = getDir(tpc, baseId)).empty()) { + LogError("Couldn't get home path"); return SECURITY_MANAGER_ERROR_UNKNOWN; } + addPkgDirs(legalPkgDirs, pkgName, isSharedRO, homePath); - std::string basePath = homePath + pkgName; - - LogDebug("Base path is : " << basePath); - legalPkgDirs.push_back(std::move(basePath)); - - if (isSdAvailable) { - std::string extendedPath; + if (extendedSdId != _TZPLATFORM_VARIABLES_INVALID_) // There might be no external storage - if (getPath(tpc, extendedSdId, pkgName, extendedPath)) - legalPkgDirs.push_back(std::move(extendedPath)); - } + if (const auto extendedSd = getDir(tpc, extendedSdId); !extendedSd.empty()) + addPkgDirs(legalPkgDirs, pkgName, false, extendedSd); if (isSkelAvailable) { - std::string skelPkgBasePath; - if (!getSkelPkgDir(pkgName, skelPkgBasePath)) + if ((skelDir = getSkelDir()).empty()) return SECURITY_MANAGER_ERROR_UNKNOWN; - legalPkgDirs.push_back(std::move(skelPkgBasePath)); - if (isSharedRO) { - std::string skelSharedROPath; - if (!getSkelPkgDir(".shared/" + pkgName, skelSharedROPath)) { - LogError("Couldn't generate skel shared RO path"); - return SECURITY_MANAGER_ERROR_UNKNOWN; - } - legalPkgDirs.push_back(std::move(skelSharedROPath)); - } + addPkgDirs(legalPkgDirs, pkgName, isSharedRO, skelDir); } - if (isSharedRO) { - std::string sharedROPath; - if (!getPath(tpc, baseId, "/.shared/" + pkgName, sharedROPath)) { - LogError("Couldn't generate sharedRO base path"); + if (SM_APP_INSTALL_LOCAL == installType) { + auto subsession = getDir(tpc, TZ_USER_HOME); + if (subsession.empty()) { + LogError("Couldn't get user home"); return SECURITY_MANAGER_ERROR_UNKNOWN; } - legalPkgDirs.push_back(std::move(sharedROPath)); - } + subsession.append("subsession/"); - if (SM_APP_INSTALL_LOCAL == installType) { subsession_user_t *userList = nullptr; int userCount; - if (SUBSESSION_ERROR_NONE != subsession_get_user_list(uid, &userList, &userCount)) { LogError("Can't determine list of users for session"); return SECURITY_MANAGER_ERROR_UNKNOWN; } - const auto userListGuard = makeUnique(userList, free); - const auto allowedLocalPath = homePath + "subsession/"; - for (int i = 0; i < userCount; i++) { - std::string newPath = allowedLocalPath - + possiblyUnterminatedArrayToString(userList[i]) + "/apps_rw/" + pkgName; - LogDebug("Adding new allowed path: " << newPath); - legalPkgDirs.emplace_back(std::move(newPath)); - } + for (int i = 0; i < userCount; i++) + // empty string means default session, skip (already added as homePath) + if (userList[i][0]) + addPkgDirs(legalPkgDirs, pkgName, isSharedRO, + subsession + possiblyUnterminatedArrayToString(userList[i]) + "/apps_rw/"); } return SECURITY_MANAGER_SUCCESS; diff --git a/test/test_service_impl_utils.cpp b/test/test_service_impl_utils.cpp index 648ea926..76fd15ef 100644 --- a/test/test_service_impl_utils.cpp +++ b/test/test_service_impl_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Samsung Electronics Co., Ltd. All rights reserved. * * This file is licensed under the terms of MIT License or the Apache License * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. @@ -99,19 +99,20 @@ NEGATIVE_FIXTURE_TEST_CASE(T263_realpath, ServiceImplUtilFixture) BOOST_REQUIRE(realPath("").empty()); } -POSITIVE_TEST_CASE(T264_getSkelPkgDir) +POSITIVE_TEST_CASE(T264_getSkelDir) { - std::string path; - BOOST_REQUIRE(getSkelPkgDir("app/bin", path)); - BOOST_REQUIRE(!path.empty()); + const auto skelDir = getSkelDir(); + BOOST_REQUIRE(!skelDir.empty()); + BOOST_REQUIRE_EQUAL(skelDir[0], '/'); + BOOST_REQUIRE_EQUAL(skelDir[skelDir.size() - 1], '/'); } NEGATIVE_FIXTURE_TEST_CASE(T265_getLegalPkgBaseDirs, ServiceImplUtilFixture) { std::vector legalPkgBaseDirs; - std::string home; + std::string home, skelDir; BOOST_REQUIRE_THROW(getLegalPkgBaseDirs(ServiceImplUtilFixture::nonexistingUid, - "pkg_name", SM_APP_INSTALL_LOCAL, home, + "pkg_name", SM_APP_INSTALL_LOCAL, home, skelDir, legalPkgBaseDirs, true), TizenPlatformConfig::Exception::ContextError); } @@ -119,27 +120,27 @@ NEGATIVE_FIXTURE_TEST_CASE(T265_getLegalPkgBaseDirs, ServiceImplUtilFixture) NEGATIVE_FIXTURE_TEST_CASE(T266_getLegalPkgBaseDirs, ServiceImplUtilFixture) { std::vector legalPkgBaseDirs; - std::string home; + std::string home, skelDir; BOOST_REQUIRE(getLegalPkgBaseDirs(0, - "pkg_name", SM_APP_INSTALL_NONE, home, + "pkg_name", SM_APP_INSTALL_NONE, home, skelDir, legalPkgBaseDirs, true) == SECURITY_MANAGER_ERROR_INPUT_PARAM); } NEGATIVE_FIXTURE_TEST_CASE(T267_getLegalPkgBaseDirs, ServiceImplUtilFixture) { std::vector legalPkgBaseDirs; - std::string home; + std::string home, skelDir; BOOST_REQUIRE(getLegalPkgBaseDirs(0, - "pkg_name", SM_APP_INSTALL_END, home, + "pkg_name", SM_APP_INSTALL_END, home, skelDir, legalPkgBaseDirs, true) == SECURITY_MANAGER_ERROR_INPUT_PARAM); } POSITIVE_FIXTURE_TEST_CASE(T268_getLegalPkgBaseDirs, ServiceImplUtilFixture) { std::vector legalPkgBaseDirs; - std::string home; + std::string home, skelDir; BOOST_REQUIRE(getLegalPkgBaseDirs(0, - "pkg_name", SM_APP_INSTALL_GLOBAL, home, + "pkg_name", SM_APP_INSTALL_GLOBAL, home, skelDir, legalPkgBaseDirs, true) == SECURITY_MANAGER_SUCCESS); } @@ -181,4 +182,5 @@ POSITIVE_TEST_CASE(T272_setRequestDefaultValues) BOOST_REQUIRE(it == SM_APP_INSTALL_GLOBAL && uid == globalUid); } + BOOST_AUTO_TEST_SUITE_END()