Fix subsession paths 85/278285/3
authorKonrad Lipinski <k.lipinski2@samsung.com>
Mon, 18 Jul 2022 10:22:49 +0000 (12:22 +0200)
committerKonrad Lipinski <k.lipinski2@samsung.com>
Mon, 18 Jul 2022 16:38:10 +0000 (18:38 +0200)
* 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

src/common/include/service_impl_utils.h
src/common/service_impl.cpp
src/common/service_impl_utils.cpp
test/test_service_impl_utils.cpp

index a024795..80d3716 100644 (file)
@@ -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<std::string> &legalPkgBaseDirs,
                         bool isSharedRO);
 
index a7e15c0..1de360f 100644 (file)
@@ -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<std::string> 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) {
index 967a909..14a7b42 100644 (file)
@@ -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<std::string> &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<std::string> &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;
index 648ea92..76fd15e 100644 (file)
@@ -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<std::string> 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<std::string> 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<std::string> 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<std::string> 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()