Add support for external storage directories 59/155559/18
authorZofia Abramowska <z.abramowska@samsung.com>
Fri, 13 Oct 2017 10:46:07 +0000 (12:46 +0200)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Thu, 26 Oct 2017 04:21:50 +0000 (04:21 +0000)
Applications can be also installed on external storages.
Security-manager has to accept such paths during application
installation. This commit adds such support for local and
global apps.

Change-Id: Idc6fa2930aa6fdcae9191844597da31ae13ecc20

src/common/include/service_impl.h
src/common/service_impl.cpp
src/include/security-manager-types.h

index 22a65e7..fa9c684 100644 (file)
@@ -318,10 +318,10 @@ private:
 
     static bool containSubDir(const std::string &parent, const pkg_paths &paths);
 
-    static bool getUserPkgDir(const uid_t &uid,
-                              const std::string &pkgName,
-                              app_install_type installType,
-                              std::string &userPkgDir);
+    static int getLegalPkgBaseDirs(const uid_t &uid,
+                                   const std::string &pkgName,
+                                   app_install_type installType,
+                                   std::vector<std::string> &legalPkgBaseDirs);
 
     static bool getSkelPkgDir(const std::string &pkgName,
                               std::string &skelPkgDir);
index b07ce23..53f7598 100644 (file)
@@ -334,37 +334,75 @@ bool ServiceImpl::containSubDir(const std::string &parent, const pkg_paths &path
     return false;
 }
 
-bool ServiceImpl::getUserPkgDir(const uid_t &uid,
-                                const std::string &pkgName,
-                                app_install_type installType,
-                                std::string &userPkgDir)
+static bool getPath(TizenPlatformConfig &tpc, enum tzplatform_variable id, const std::string &subDir, std::string &path)
+{
+    path = realPath(tpc.ctxGetEnv(id));
+    if (path.empty())
+        return false;
+
+    path += "/" + subDir;
+
+    return true;
+}
+
+int ServiceImpl::getLegalPkgBaseDirs(const uid_t &uid,
+                                     const std::string &pkgName,
+                                     app_install_type installType,
+                                     std::vector<std::string> &legalPkgDirs)
 {
     TizenPlatformConfig tpc(uid);
 
-    enum tzplatform_variable id;
+    bool isSdAvailable = false;
+    bool isSkelAvailable = false;
+    enum tzplatform_variable baseId;
+    enum tzplatform_variable extendedSdId;
 
     switch (installType) {
     case SM_APP_INSTALL_LOCAL:
-        id = TZ_USER_APP;
+        isSdAvailable = true;
+        baseId = TZ_USER_APP;
+        extendedSdId = TZ_USER_EXTENDEDSD_APP;
         break;
     case SM_APP_INSTALL_GLOBAL:
-        id = TZ_SYS_RW_APP;
+        isSdAvailable = true;
+        isSkelAvailable = true;
+        baseId = TZ_SYS_RW_APP;
+        extendedSdId = TZ_SYS_EXTENDEDSD_APP;
         break;
     case SM_APP_INSTALL_PRELOADED:
-        id = TZ_SYS_RO_APP;
+        isSkelAvailable = true;
+        baseId = TZ_SYS_RO_APP;
         break;
     default:
         LogError("Unsupported installation type: " << installType);
-        return false;
+        return SECURITY_MANAGER_ERROR_INPUT_PARAM;
     }
 
-    userPkgDir = std::move(realPath(tpc.ctxGetEnv(id)));
-    if (userPkgDir.empty())
-        return false;
+    legalPkgDirs.clear();
+
+    std::string basePath;
+    if (!getPath(tpc, baseId, pkgName, basePath)) {
+        LogError("Couldn't generate base path");
+        return SECURITY_MANAGER_ERROR_UNKNOWN;
+    }
 
-    userPkgDir.append("/").append(pkgName);
+    LogDebug("Base path is : " << basePath);
+    legalPkgDirs.push_back(std::move(basePath));
 
-    return true;
+    if (isSdAvailable) {
+        std::string extendedPath;
+        // There might be no external storage
+        if (getPath(tpc, extendedSdId, pkgName, extendedPath))
+            legalPkgDirs.push_back(std::move(extendedPath));
+    }
+
+    if (isSkelAvailable) {
+        std::string skelPkgBasePath;
+        if (!getSkelPkgDir(pkgName, skelPkgBasePath))
+            return SECURITY_MANAGER_ERROR_UNKNOWN;
+        legalPkgDirs.push_back(std::move(skelPkgBasePath));
+    }
+    return SECURITY_MANAGER_SUCCESS;
 }
 
 bool ServiceImpl::getSkelPkgDir(const std::string &pkgName,
@@ -373,7 +411,7 @@ bool ServiceImpl::getSkelPkgDir(const std::string &pkgName,
     std::string app = TizenPlatformConfig::getEnv(TZ_USER_APP);
     std::string home = TizenPlatformConfig::getEnv(TZ_USER_HOME);
     std::string real_skel_dir = std::move(realPath(Config::SKEL_DIR));
-    if (app.empty() || home.empty() || real_skel_dir.empty()) {
+    if (real_skel_dir.empty()) {
         LogError("Unable to get skel pkg dir.");
         return false;
     }
@@ -450,35 +488,24 @@ int ServiceImpl::labelPaths(const pkg_paths &paths,
                             const uid_t &uid)
 {
     try {
-        std::string pkgBasePath;
-        int authorId;
-
         if (!m_privilegeDb.PkgNameExists(pkgName)) {
             LogError("No such package: " << pkgName);
             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
         }
 
+        int authorId;
         m_privilegeDb.GetPkgAuthorId(pkgName, authorId);
 
-        if (!getUserPkgDir(uid, pkgName, installationType, pkgBasePath))
-            return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-
-        // check if paths are inside
-        bool pathsOK;
-        if (installationType == SM_APP_INSTALL_LOCAL) {
-            pathsOK = pathsCheck(paths, {pkgBasePath});
-        } else {
-            std::string skelPkgBasePath;
-            if (!getSkelPkgDir(pkgName, skelPkgBasePath))
-                return SECURITY_MANAGER_ERROR_SERVER_ERROR;
-            pathsOK = pathsCheck(paths, {pkgBasePath, skelPkgBasePath});
+        std::vector<std::string> pkgLegalBaseDirs;
+        int ret = getLegalPkgBaseDirs(uid, pkgName, installationType, pkgLegalBaseDirs);
+        if (ret != SECURITY_MANAGER_SUCCESS) {
+            LogError("Failed to generate legal directories for application");
+            return ret;
         }
 
-        if (!pathsOK)
-            return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
-
-        if (containSubDir(pkgBasePath, paths))
-            SmackLabels::setupPkgBasePath(pkgBasePath);
+        // check if paths are inside of legal directories
+        if (!pathsCheck(paths, pkgLegalBaseDirs))
+            return SECURITY_MANAGER_ERROR_NOT_PATH_OWNER;
 
         // register paths
         for (const auto &pkgPath : paths) {
@@ -486,6 +513,13 @@ int ServiceImpl::labelPaths(const pkg_paths &paths,
             app_install_path_type pathType = static_cast<app_install_path_type>(pkgPath.second);
             SmackLabels::setupPath(pkgName, path, pathType, authorId);
         }
+
+        for (const auto &basePath : pkgLegalBaseDirs) {
+            if (containSubDir(basePath, paths)) {
+                SmackLabels::setupPkgBasePath(basePath);
+            }
+        }
+
         return SECURITY_MANAGER_SUCCESS;
     } catch (const PrivilegeDb::Exception::Base &e) {
         LogError("Database error: " << e.DumpToString());
index c28a9f4..f7fa2eb 100644 (file)
@@ -53,6 +53,7 @@ enum lib_retcode {
     SECURITY_MANAGER_ERROR_FILE_CREATE_FAILED,
     SECURITY_MANAGER_ERROR_FILE_DELETE_FAILED,
     SECURITY_MANAGER_ERROR_MOUNT_ERROR,
+    SECURITY_MANAGER_ERROR_NOT_PATH_OWNER
 };
 
 /*! \brief accesses types for application installation paths*/