Add API for sensitive path registration 43/112243/7
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 30 Jan 2017 11:08:34 +0000 (12:08 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Wed, 1 Mar 2017 09:25:10 +0000 (10:25 +0100)
Change-Id: I1009c7ee5620881e4fbf775439de70788ae78a7f

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

index 3366f7faa65427040642b143454ab1deedc1411e..b7edf47de6c6fc225512a5461bf4a694f8f93bfe 100644 (file)
@@ -43,6 +43,7 @@ static std::map <std::string, enum app_install_path_type> app_install_path_type_
     {"public_ro", SECURITY_MANAGER_PATH_PUBLIC_RO},
     {"rw_others_ro", SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO},
     {"trusted_rw", SECURITY_MANAGER_PATH_TRUSTED_RW},
+    {"rw_sensitive", SECURITY_MANAGER_PATH_RW_SENSITIVE},
 };
 
 static std::map <std::string, enum security_manager_user_type> user_type_map = {
@@ -89,7 +90,7 @@ static po::options_description getInstallOptions()
          ("path,p", po::value< std::vector<std::string> >()->multitoken(),
           "path for setting smack labels (may occur more than once).\n"
           "Format: --path <path> <path type>\n"
-          "  where <path type> is: \trw, ro, public_ro, rw_others_ro, trusted_rw\n"
+          "  where <path type> is: \trw, ro, public_ro, rw_others_ro, trusted_rw, rw_sensitive\n"
           "  ('trusted rw' requires author id)\n"
           "example:\n"
           "        \t--path=/home/user/app rw")
index 46c9f247d37a448427e5162f22c9cb5f50c77d4c..aeeb1693420e0a6a36e4967b4c0ea3576e024c76 100644 (file)
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 
 #include <vector>
+#include <set>
 
 #include "credentials.h"
 #include "cynara.h"
@@ -280,7 +281,7 @@ private:
 
     void getPkgLabels(const std::string &pkgName, SmackRules::Labels &pkgsLabels);
 
-    static bool isSharedRO(const pkg_paths& paths);
+    static bool containsPathType(const pkg_paths& paths, const std::set<app_install_path_type> &types);
 
     int squashDropPrivateSharing(const std::string &ownerAppName,
                                  const std::string &targetAppName,
@@ -305,6 +306,11 @@ private:
 
     int validatePolicy(const Credentials &creds, policy_entry &policyEntry, CynaraAdminPolicy &cyap);
 
+    int registerSensitiveDirs(const pkg_paths &paths,
+                              int installType,
+                              const std::string &pkgName,
+                              uid_t uid);
+
     Cynara m_cynara;
     PrivilegeDb m_priviligeDb;
     CynaraAdmin m_cynaraAdmin;
index bc66995a45c8e046be9126e5bcedc6580723c47c..103d7b8ef127d4b6d7da87fb284a93735a7c431b 100644 (file)
@@ -445,11 +445,11 @@ int ServiceImpl::labelPaths(const pkg_paths &paths,
     }
 }
 
-bool ServiceImpl::isSharedRO(const pkg_paths& paths)
+bool ServiceImpl::containsPathType(const pkg_paths &paths, const std::set<app_install_path_type> &types)
 {
     for (const auto& pkgPath : paths) {
         auto pathType = static_cast<app_install_path_type>(pkgPath.second);
-        if (pathType == SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO)
+        if (types.find(pathType) != types.end())
             return true;
     }
 
@@ -485,6 +485,30 @@ void ServiceImpl::updatePermissibleSet(uid_t uid, int type)
     PermissibleSet::updatePermissibleFile(uid, type, labelsForUser);
 }
 
+int ServiceImpl::registerSensitiveDirs(const pkg_paths &paths,
+                                       int installType,
+                                       const std::string &pkgName,
+                                       uid_t uid)
+{
+    for (const auto &path : paths) {
+        if (path.second != SECURITY_MANAGER_PATH_RW_SENSITIVE)
+            continue;
+
+        /*
+         * Sensitive(RW) directories do not make sense for global installation.
+         * The app should store data in user's home dir (locally)
+         */
+        if (installType == SM_APP_INSTALL_GLOBAL || installType == SM_APP_INSTALL_PRELOADED) {
+            LogError("Registering sensitive directory for global app is not allowed");
+            return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+        }
+
+        // directories will be automatically removed from db upon pkg removal
+        m_priviligeDb.AddSensitiveDir(pkgName, uid, path.first);
+    }
+    return SECURITY_MANAGER_SUCCESS;
+}
+
 int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
 {
     SmackRules::Labels pkgLabels;
@@ -495,7 +519,7 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
     SmackRules::PkgsLabels pkgsProcessLabels;
     int authorId;
     std::vector<PkgInfo> pkgsInfo;
-    bool hasSharedRO = isSharedRO(req.pkgPaths);
+    bool hasSharedRO = containsPathType(req.pkgPaths, {SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO} );
 
     try {
         setRequestDefaultValues(req.uid, req.installationType);
@@ -533,6 +557,14 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
         m_priviligeDb.GetPackagesInfo(pkgsInfo);
         getPkgsProcessLabels(pkgsInfo, pkgsProcessLabels);
 
+        for (const auto &path : req.pkgPaths) {
+            if (path.second == SECURITY_MANAGER_PATH_RW_SENSITIVE) {
+                LogError("Sensitive paths not supported in APP_INSTALL request."
+                         "Use PATHS_REGISTER.");
+                return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+            }
+        }
+
         // WTF? Why this commit is here? Shouldn't it be at the end of this function?
         trans.commit();
         LogDebug("Application installation commited to database");
@@ -1585,9 +1617,18 @@ int ServiceImpl::pathsRegister(const Credentials &creds, path_req req)
     }
 
     try {
-        if (isSharedRO(req.pkgPaths)) {
+        if (containsPathType(req.pkgPaths, {SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, SECURITY_MANAGER_PATH_RW_SENSITIVE})) {
             ScopedTransaction trans(m_priviligeDb);
 
+            if (!m_priviligeDb.PkgNameExists(req.pkgName)) {
+                LogError("No such package: " << req.pkgName);
+                return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+            }
+
+            int ret = registerSensitiveDirs(req.pkgPaths, req.installationType, req.pkgName, req.uid);
+            if (ret != SECURITY_MANAGER_SUCCESS)
+                return ret;
+
             if (!m_priviligeDb.IsPackageSharedRO(req.pkgName)) {
 
                 m_priviligeDb.SetSharedROPackage(req.pkgName);
index e6236532274bfa09c6cfa0daad40e61f609f2bf7..4c4c882f8655a9fc3fc81b01cc59b5b5d35abc97 100644 (file)
@@ -142,6 +142,7 @@ void setupPath(
 
     switch (pathType) {
     case SECURITY_MANAGER_PATH_RW:
+    case SECURITY_MANAGER_PATH_RW_SENSITIVE:
         label = generatePathRWLabel(pkgName);
         label_executables = false;
         label_transmute = true;
index dfc331783843c9b2d7393e9b5dfa581388ffdf0d..aea3deae454bfd62549d7380439f55c718cdc8e3 100644 (file)
@@ -66,6 +66,8 @@ enum app_install_path_type {
     SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO,
     //! RW access for application packages coming from the same author
     SECURITY_MANAGER_PATH_TRUSTED_RW,
+    //! RW access for given application package. Can be encrypted
+    SECURITY_MANAGER_PATH_RW_SENSITIVE,
     //! this is only for range limit
     SECURITY_MANAGER_ENUM_END
 };