From: Rafal Krypa Date: Mon, 31 Aug 2015 18:07:21 +0000 (+0200) Subject: Adapt application file labeling to new requirements X-Git-Tag: accepted/tizen/mobile/20150903.053522~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git;a=commitdiff_plain;h=db5ca0b66e160adb63e587936f05a40cc797b92d Adapt application file labeling to new requirements The following changes has been made: - application base path must now be APPS_ROOT/$pkgID, not APPS_ROOT/$pkgID/$appID - application base path is now enforced, no files outside base path allowed - application base path will be labeled with User::Pkg::$pkgID, no transmute - SECURITY_MANAGER_PATH_TYPE_RO will be labeled with User::Pkg::$pkgID::RO - applications get a Smack rule for RO access to User::Pkg::$pkgID::RO - SECURITY_MANAGER_PATH_PUBLIC_RO will be labeled with User::Home - SECURITY_MANAGER_PATH_PRIVATE and SECURITY_MANAGER_PATH_PUBLIC path types Change-Id: I2d0260effcbe8da0c0e9130b89b4b34e7e104d29 Signed-off-by: Rafal Krypa --- diff --git a/policy/app-rules-template.smack b/policy/app-rules-template.smack index d0b6fb2..5bb1639 100644 --- a/policy/app-rules-template.smack +++ b/policy/app-rules-template.smack @@ -4,9 +4,11 @@ System ~APP~ rwx ~APP~ System::Run rwxat ~APP~ System::Log rwxa ~APP~ _ l -User ~APP~ rwxa +User ~APP~ rwx User ~PKG~ rwxat +User ~PKG~::RO rwxat ~APP~ User wx ~APP~ User::Home rxl ~APP~ User::App::Shared rwxat ~APP~ ~PKG~ rwxat +~APP~ ~PKG~::RO rxl diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h index 0b6e3c6..ccf5e78 100644 --- a/src/common/include/service_impl.h +++ b/src/common/include/service_impl.h @@ -43,7 +43,7 @@ private: static bool getUserAppDir(const uid_t &uid, std::string &userAppDir); - static bool installRequestAuthCheck(const app_inst_req &req, uid_t uid, bool &isCorrectPath, std::string &appPath); + static bool installRequestAuthCheck(const app_inst_req &req, uid_t uid, std::string &appPath); static bool getZoneId(std::string &zoneId); diff --git a/src/common/include/smack-labels.h b/src/common/include/smack-labels.h index b454eff..1a68f1e 100644 --- a/src/common/include/smack-labels.h +++ b/src/common/include/smack-labels.h @@ -37,49 +37,22 @@ namespace SmackLabels { /** * Sets Smack labels on a directory and its contents, recursively. * - * @param appId[in] application's identifier - * @param path[in] path to a file or directory to setup - * @param pathType[in] type of path to setup. See description of - * app_install_path_type in security-manager.h for details - * - */ -void setupPath(const std::string &appId, const std::string &path, - app_install_path_type pathType); - -/** - * Sets Smack labels on a directory and its contents, recursively. - * - * @param appId[in] application's identifier + * @param pkgId[in] application's package identifier * @param path[in] path to a file or directory to setup * @param pathType[in] type of path to setup. See description of * app_install_path_type in security-manager.h for details * @param zoneId[in] ID of zone for which label should be set */ -void setupPath(const std::string &appId, const std::string &path, +void setupPath(const std::string &pkgId, const std::string &path, app_install_path_type pathType, const std::string &zoneId); /** - * Sets Smack labels on a / and // - * non-recursively + * Sets Smack labels on a / non-recursively * * @param pkgId[in] package identifier - * @param appId[in] application's identifier * @param basePath[in] path */ -void setupCorrectPath(const std::string &pkgId, const std::string &appId, - const std::string &basePath); - -/** - * Sets Smack labels on a / and // - * non-recursively - * - * @param pkgId[in] package identifier - * @param appId[in] application's identifier - * @param basePath[in] path - * @param zoneId[in] ID of zone for which label should be set - */ -void setupCorrectPath(const std::string &pkgId, const std::string &appId, - const std::string &basePath, const std::string &zoneId); +void setupAppBasePath(const std::string &pkgId, const std::string &basePath); /** * Generates application name for a label fetched from Cynara @@ -105,6 +78,15 @@ std::string generateAppLabel(const std::string &appId); */ std::string generatePkgLabel(const std::string &pkgId); +/** + * Generates label for private application RO files with package ID @ref pkgId + * + * @param[in] pkgId + * @return resulting Smack label + */ +std::string generatePkgROLabel(const std::string &pkgId); + + } // namespace SmackLabels } // namespace SecurityManager diff --git a/src/common/include/smack-rules.h b/src/common/include/smack-rules.h index 5aadc12..c67c370 100644 --- a/src/common/include/smack-rules.h +++ b/src/common/include/smack-rules.h @@ -155,6 +155,17 @@ private: */ static void uninstallRules (const std::string &path); + /** + * Helper method: replace all occurrences of \ref needle in \ref haystack + * with \ref replace. + * + * @param[in,out] haystack string to modify + * @param needle string to find in \ref haystack + * @param replace string to replace \ref needle with + */ + static void strReplace(std::string &haystack, const std::string &needle, + const std::string &replace); + smack_accesses *m_handle; }; diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp index 3f959a9..469f6a4 100644 --- a/src/common/service_impl.cpp +++ b/src/common/service_impl.cpp @@ -168,7 +168,7 @@ bool ServiceImpl::isSubDir(const char *parent, const char *subdir) if (*parent++ != *subdir++) return false; - return (*subdir == '/'); + return (*subdir == '/' || *parent == *subdir); } bool ServiceImpl::getUserAppDir(const uid_t &uid, std::string &userAppDir) @@ -201,7 +201,7 @@ bool ServiceImpl::getUserAppDir(const uid_t &uid, std::string &userAppDir) return true; } -bool ServiceImpl::installRequestAuthCheck(const app_inst_req &req, uid_t uid, bool &isCorrectPath, std::string &appPath) +bool ServiceImpl::installRequestAuthCheck(const app_inst_req &req, uid_t uid, std::string &appPath) { std::string userHome; std::string userAppDir; @@ -219,7 +219,7 @@ bool ServiceImpl::installRequestAuthCheck(const app_inst_req &req, uid_t uid, bo appPath = userAppDir; correctPath.clear(); - correctPath << userAppDir << "/" << req.pkgId << "/" << req.appId; + correctPath << userAppDir << "/" << req.pkgId; LogDebug("correctPath: " << correctPath.str()); for (const auto &appPath : req.appPaths) { @@ -232,20 +232,8 @@ bool ServiceImpl::installRequestAuthCheck(const app_inst_req &req, uid_t uid, bo } LogDebug("Requested path is '" << appPath.first.c_str() << "'. User's APPS_DIR is '" << userAppDir << "'"); - if (!isSubDir(userAppDir.c_str(), real_path.get())) { - LogWarning("User's apps may have registered folders only in user's APPS_DIR"); - return false; - } - if (!isSubDir(correctPath.str().c_str(), real_path.get())) { - LogWarning("Installation is outside correct path: " << correctPath.str()); - //return false; - } else - isCorrectPath = true; - - app_install_path_type pathType = static_cast(appPath.second); - if (pathType == SECURITY_MANAGER_PATH_PUBLIC) { - LogWarning("Only root can register SECURITY_MANAGER_PATH_PUBLIC path"); + LogWarning("Installation is outside correct path: " << correctPath.str() << "," << real_path.get()); return false; } } @@ -274,7 +262,6 @@ int ServiceImpl::appInstall(const app_inst_req &req, uid_t uid, bool isSlave) std::vector removedPermissions; std::vector pkgContents; std::string uidstr; - bool isCorrectPath = false; std::string appPath; std::string appLabel; std::string pkgLabel; @@ -299,7 +286,7 @@ int ServiceImpl::appInstall(const app_inst_req &req, uid_t uid, bool isSlave) } checkGlobalUser(uid, uidstr); - if (!installRequestAuthCheck(req, uid, isCorrectPath, appPath)) { + if (!installRequestAuthCheck(req, uid, appPath)) { LogError("Request from uid " << uid << " for app installation denied"); return SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED; } @@ -365,14 +352,14 @@ int ServiceImpl::appInstall(const app_inst_req &req, uid_t uid, bool isSlave) } try { - if (isCorrectPath) - SmackLabels::setupCorrectPath(req.pkgId, req.appId, appPath, zoneId); + if (!req.appPaths.empty()) + SmackLabels::setupAppBasePath(req.pkgId, appPath); // register paths for (const auto &appPath : req.appPaths) { const std::string &path = appPath.first; app_install_path_type pathType = static_cast(appPath.second); - SmackLabels::setupPath(req.appId, path, pathType, zoneId); + SmackLabels::setupPath(req.pkgId, path, pathType, zoneId); } if (isSlave) { diff --git a/src/common/smack-labels.cpp b/src/common/smack-labels.cpp index 236d090..c01d555 100644 --- a/src/common/smack-labels.cpp +++ b/src/common/smack-labels.cpp @@ -42,8 +42,8 @@ namespace SecurityManager { namespace SmackLabels { -/* Const defined below is used to label files accessible to apps only for reading */ -const char *const LABEL_FOR_APP_RO_PATH = "User::Home"; +//! Smack label used for SECURITY_MANAGER_PATH_PUBLIC_RO paths (RO for all apps) +const char *const LABEL_FOR_APP_PUBLIC_RO_PATH = "User::Home"; typedef std::function LabelDecisionFn; @@ -126,34 +126,27 @@ static void labelDir(const std::string &path, const std::string &label, dirSetSmack(path, label, XATTR_NAME_SMACKEXEC, &labelExecs); } -void setupPath(const std::string &appId, const std::string &path, app_install_path_type pathType) -{ - setupPath(appId, path, pathType, std::string()); -} - -void setupPath(const std::string &appId, const std::string &path, app_install_path_type pathType, +void setupPath(const std::string &pkgId, const std::string &path, app_install_path_type pathType, const std::string &zoneId) { std::string label; bool label_executables, label_transmute; switch (pathType) { - case SECURITY_MANAGER_PATH_PRIVATE: case SECURITY_MANAGER_PATH_RW: - label = zoneSmackLabelGenerate(generateAppLabel(appId), zoneId); + label = zoneSmackLabelGenerate(generatePkgLabel(pkgId), zoneId); label_executables = true; label_transmute = false; break; - case SECURITY_MANAGER_PATH_PUBLIC: case SECURITY_MANAGER_PATH_RO: - label.assign(LABEL_FOR_APP_RO_PATH); + label = zoneSmackLabelGenerate(generatePkgROLabel(pkgId), zoneId); label_executables = false; - label_transmute = true; + label_transmute = false; break; case SECURITY_MANAGER_PATH_PUBLIC_RO: - label.assign("_"); + label.assign(LABEL_FOR_APP_PUBLIC_RO_PATH); label_executables = false; - label_transmute = false; + label_transmute = true; break; default: LogError("Path type not known."); @@ -162,20 +155,10 @@ void setupPath(const std::string &appId, const std::string &path, app_install_pa return labelDir(path, label, label_transmute, label_executables); } -void setupCorrectPath(const std::string &pkgId, const std::string &appId, const std::string &basePath) -{ - setupCorrectPath(pkgId, appId, basePath, std::string()); -} - -void setupCorrectPath(const std::string &pkgId, const std::string &appId, const std::string &basePath, - const std::string& zoneId) +void setupAppBasePath(const std::string &pkgId, const std::string &basePath) { std::string pkgPath = basePath + "/" + pkgId; - std::string appPath = pkgPath + "/" + appId; - - pathSetSmack(pkgPath.c_str(), zoneSmackLabelGenerate(generatePkgLabel(pkgId), zoneId), XATTR_NAME_SMACK); - pathSetSmack(appPath.c_str(), zoneSmackLabelGenerate(generateAppLabel(appId), zoneId), XATTR_NAME_SMACK); - pathSetSmack(appPath.c_str(), "TRUE", XATTR_NAME_SMACKTRANSMUTE); + pathSetSmack(pkgPath.c_str(), LABEL_FOR_APP_PUBLIC_RO_PATH, XATTR_NAME_SMACK); } std::string generateAppNameFromLabel(const std::string &label) @@ -208,5 +191,16 @@ std::string generatePkgLabel(const std::string &pkgId) return label; } +std::string generatePkgROLabel(const std::string &pkgId) +{ + std::string label = "User::Pkg::" + pkgId + "::RO"; + + if (smack_label_length(label.c_str()) <= 0) + ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from pkgId " << pkgId); + + return label; +} + + } // namespace SmackLabels } // namespace SecurityManager diff --git a/src/common/smack-rules.cpp b/src/common/smack-rules.cpp index d3bdf22..ce4f6e2 100644 --- a/src/common/smack-rules.cpp +++ b/src/common/smack-rules.cpp @@ -177,17 +177,10 @@ void SmackRules::addFromTemplate(const std::vector &templateRules, ThrowMsg(SmackException::FileError, "Invalid rule template: " << rule); } - if (subject == SMACK_APP_LABEL_TEMPLATE) - subject = SmackLabels::generateAppLabel(appId); - - if (subject == SMACK_PKG_LABEL_TEMPLATE) - subject = SmackLabels::generatePkgLabel(pkgId); - - if (object == SMACK_APP_LABEL_TEMPLATE) - object = SmackLabels::generateAppLabel(appId); - - if (object == SMACK_PKG_LABEL_TEMPLATE) - object = SmackLabels::generatePkgLabel(pkgId); + strReplace(subject, SMACK_APP_LABEL_TEMPLATE, SmackLabels::generateAppLabel(appId)); + strReplace(subject, SMACK_PKG_LABEL_TEMPLATE, SmackLabels::generatePkgLabel(pkgId)); + strReplace(object, SMACK_APP_LABEL_TEMPLATE, SmackLabels::generateAppLabel(appId)); + strReplace(object, SMACK_PKG_LABEL_TEMPLATE, SmackLabels::generatePkgLabel(pkgId)); if (!zoneId.empty()) { // FIXME replace with vasum calls. See zone-utils.h @@ -307,4 +300,12 @@ void SmackRules::uninstallRules(const std::string &path) } } +void SmackRules::strReplace(std::string &haystack, const std::string &needle, + const std::string &replace) +{ + size_t pos; + while ((pos = haystack.find(needle)) != std::string::npos) + haystack.replace(pos, needle.size(), replace); +} + } // namespace SecurityManager diff --git a/src/include/security-manager.h b/src/include/security-manager.h index 3c1304e..d9a735e 100644 --- a/src/include/security-manager.h +++ b/src/include/security-manager.h @@ -46,17 +46,13 @@ enum lib_retcode { /*! \brief accesses types for application installation paths*/ enum app_install_path_type { - //accessible read-write only for applications with same package id - SECURITY_MANAGER_PATH_PRIVATE, - //read-write access for all applications - SECURITY_MANAGER_PATH_PUBLIC, - //read only access for all applications + //! RO access for all applications SECURITY_MANAGER_PATH_PUBLIC_RO, - //accessible for writing to all apps within its package + //! RW access for given application package SECURITY_MANAGER_PATH_RW, - //accessible to apps for reading + //! RO access for given application package SECURITY_MANAGER_PATH_RO, - //this is only for range limit + //! this is only for range limit SECURITY_MANAGER_ENUM_END };