summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZofia Abramowska <z.abramowska@samsung.com>2016-09-08 18:29:45 +0200
committerRafal Krypa <r.krypa@samsung.com>2016-09-28 18:13:09 +0200
commit5b9adf81b4bba82e9a6ace62bc3ac43f6e873519 (patch)
tree93934a5258e601017348c75d160fc52aacde2f40
parente831af8e2928a20d2a46b74ffdbd0e0e046cee03 (diff)
downloadsecurity-manager-5b9adf81b4bba82e9a6ace62bc3ac43f6e873519.tar.gz
security-manager-5b9adf81b4bba82e9a6ace62bc3ac43f6e873519.tar.bz2
security-manager-5b9adf81b4bba82e9a6ace62bc3ac43f6e873519.zip
Change the way of app process label generation
Application process label depends on isHybrid flag, if flag value is: * 0 - all applications in package has the same process label: "User::Pkg::pkg_id" * 1 - each application in package has different process label: "User::Pkg::pkg_id::App::app_Id" Due to this change, app identifying API changes its behaviour: for hybrid applications both app_id and pkg_id are returned, for non-hybrid applications only pkg_id is returned. From now on identyfing particular application is not always possible. Change-Id: Ice62b03be632524ec452569b6c8419f357db1b7f
-rw-r--r--src/client/client-security-manager.cpp15
-rw-r--r--src/common/include/smack-labels.h4
-rw-r--r--src/common/service_impl.cpp97
-rw-r--r--src/common/smack-labels.cpp35
-rw-r--r--src/include/app-runtime.h7
5 files changed, 112 insertions, 46 deletions
diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp
index 5f30c203..30b631a5 100644
--- a/src/client/client-security-manager.cpp
+++ b/src/client/client-security-manager.cpp
@@ -1295,21 +1295,24 @@ static lib_retcode get_app_and_pkg_id_from_smack_label(
char **pkg_name,
char **app_name)
{
- std::string appNameString;
-
+ std::string appNameString, pkgNameString;
try {
- appNameString = SmackLabels::generateAppNameFromLabel(label);
+
+ SmackLabels::generateAppPkgNameFromLabel(label, appNameString, pkgNameString);
} catch (const SmackException::InvalidLabel &) {
return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
}
- if (app_name && !(*app_name = strdup(appNameString.c_str()))) {
+ if (app_name && !appNameString.empty() && !(*app_name = strdup(appNameString.c_str()))) {
LogError("Memory allocation in strdup failed.");
return SECURITY_MANAGER_ERROR_MEMORY;
}
- return pkg_name ? static_cast<lib_retcode>(security_manager_get_app_pkgid(pkg_name, appNameString.c_str()))
- : SECURITY_MANAGER_SUCCESS;
+ if (pkg_name && !(*pkg_name = strdup(pkgNameString.c_str()))) {
+ LogError("Memory allocation in strdup failed.");
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+ return SECURITY_MANAGER_SUCCESS;
}
static int security_manager_identify_app(
diff --git a/src/common/include/smack-labels.h b/src/common/include/smack-labels.h
index 213e4068..9ad95b96 100644
--- a/src/common/include/smack-labels.h
+++ b/src/common/include/smack-labels.h
@@ -67,9 +67,11 @@ void setupSharedPrivatePath(const std::string &pkgName, const std::string &path)
* Generates application name for a label fetched from Cynara
*
* @param[in] label string to fetch application name for
+ * @param[out] appName application identifier (can be empty if label belongs to non-hybrid app)
+ * @param[out] pkgName package identifier (cannot be empty)
* @return application name on success, empty string on error.
*/
-std::string generateAppNameFromLabel(const std::string &label);
+void generateAppPkgNameFromLabel(const std::string &label, std::string &appName, std::string &pkgName);
/**
* Generates label for an application identifier
diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp
index 79fc050c..72d97244 100644
--- a/src/common/service_impl.cpp
+++ b/src/common/service_impl.cpp
@@ -70,6 +70,10 @@ static std::string getAppProcessLabel(const std::string &appName)
{
std::string pkgName;
PrivilegeDb::getInstance().GetAppPkgName(appName, pkgName);
+ if (pkgName.empty()) {
+ LogWarning("Cannot create label for unknown application: " << appName);
+ return "";
+ }
return getAppProcessLabel(appName, pkgName);
}
@@ -138,9 +142,19 @@ static inline int validatePolicy(policy_entry &policyEntry, std::string uidStr,
if (!policyEntry.privilege.compare(SECURITY_MANAGER_ANY))
policyEntry.privilege = CYNARA_ADMIN_WILDCARD;
+ std::string cynaraClient;
+ if (policyEntry.appName.compare(SECURITY_MANAGER_ANY)) {
+ cynaraClient = getAppProcessLabel(policyEntry.appName);
+ if (cynaraClient.empty()) {
+ LogWarning("Cannot set policy for unknown application " << policyEntry.appName);
+ return SECURITY_MANAGER_ERROR_APP_UNKNOWN;
+ }
+ } else {
+ cynaraClient = CYNARA_ADMIN_WILDCARD;
+ }
+
cyap = std::move(CynaraAdminPolicy(
- policyEntry.appName.compare(SECURITY_MANAGER_ANY) ?
- getAppProcessLabel(policyEntry.appName) : CYNARA_ADMIN_WILDCARD,
+ cynaraClient,
policyEntry.user,
policyEntry.privilege,
level,
@@ -633,6 +647,7 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
std::map<std::string, std::vector<std::string>> asOwnerSharing;
std::map<std::string, std::vector<std::string>> asTargetSharing;
int authorId;
+ bool isPkgHybrid;
installRequestMangle(req, cynaraUserStr);
@@ -656,6 +671,7 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
return SECURITY_MANAGER_SUCCESS;
}
+ isPkgHybrid = PrivilegeDb::getInstance().IsPackageHybrid(req.pkgName);
processLabel = getAppProcessLabel(req.appName, req.pkgName);
LogDebug("Generated uninstall parameters: pkgName=" << req.pkgName
<< " Smack label=" << processLabel);
@@ -741,7 +757,13 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
try {
if (removeApp) {
LogDebug("Removing Smack rules for appName " << req.appName);
- SmackRules::uninstallApplicationRules(req.appName, processLabel);
+ if (isPkgHybrid || removePkg) {
+ /*
+ * Nonhybrid apps have the same label, so revoking it is unnecessary
+ * unless whole packagee is being removed.
+ */
+ SmackRules::uninstallApplicationRules(req.appName, processLabel);
+ }
LogDebug("Removing Smack rules for pkgName " << req.pkgName);
SmackRules::uninstallPackageRules(req.pkgName);
if (!removePkg) {
@@ -753,7 +775,7 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
SmackRules::generateSharedRORules(pkgsProcessLabels, sharedROPkgs);
if (removePkg)
- SmackRules::revokeSharedRORules(pkgsProcessLabels, req.pkgName);
+ SmackRules::revokeSharedRORules(pkgsProcessLabels, req.pkgName);
}
if (authorId != -1 && removeAuthor) {
@@ -1058,32 +1080,57 @@ int ServiceImpl::getConfiguredPolicy(const Credentials &creds, bool forAdmin,
continue;
policy_entry pe;
-
- pe.appName = strcmp(policy.client, CYNARA_ADMIN_WILDCARD) ? SmackLabels::generateAppNameFromLabel(policy.client) : SECURITY_MANAGER_ANY;
- pe.user = strcmp(policy.user, CYNARA_ADMIN_WILDCARD) ? policy.user : SECURITY_MANAGER_ANY;
- pe.privilege = strcmp(policy.privilege, CYNARA_ADMIN_WILDCARD) ? policy.privilege : pe.privilege = SECURITY_MANAGER_ANY;
- pe.currentLevel = CynaraAdmin::getInstance().convertToPolicyDescription(policy.result);
-
- if (!forAdmin) {
- // All policy entries in PRIVACY_MANAGER should be fully-qualified
- pe.maxLevel = CynaraAdmin::getInstance().convertToPolicyDescription(
- CynaraAdmin::getInstance().GetPrivilegeManagerMaxLevel(
- policy.client, policy.user, policy.privilege));
+ std::vector<std::string> appNames;
+ std::string appName, pkgName;
+
+ if (strcmp(policy.client, CYNARA_ADMIN_WILDCARD)) {
+ SmackLabels::generateAppPkgNameFromLabel(policy.client, appName, pkgName);
+ if (!appName.empty()) {
+ // Hybrid app
+ appNames.push_back(appName);
+ } else {
+ if (filter.appName == SECURITY_MANAGER_ANY) {
+ // If user requested policy for all apps, we have to demangle pkgName to
+ // set of appNames in case of non-hybrid apps
+ PrivilegeDb::getInstance().GetPkgApps(pkgName, appNames);
+ } else {
+ // If user requested policy for specific appName, we have to copy
+ // appName from filter for non-hybrid apps
+ appNames.push_back(filter.appName);
+ }
+ }
} else {
- // Cannot reliably calculate maxLavel for policies from ADMIN bucket
- pe.maxLevel = CynaraAdmin::getInstance().convertToPolicyDescription(CYNARA_ADMIN_ALLOW);
+ // Cynara wildcard -> SM any
+ appNames.push_back(SECURITY_MANAGER_ANY);
}
+ for (const auto &app : appNames) {
+ pe.appName = app;
+ pe.user = strcmp(policy.user, CYNARA_ADMIN_WILDCARD) ? policy.user : SECURITY_MANAGER_ANY;
+ pe.privilege = strcmp(policy.privilege, CYNARA_ADMIN_WILDCARD) ? policy.privilege : pe.privilege = SECURITY_MANAGER_ANY;
+ pe.currentLevel = CynaraAdmin::getInstance().convertToPolicyDescription(policy.result);
- LogDebug(
- "[policy_entry] app: " << pe.appName
- << " user: " << pe.user
- << " privilege: " << pe.privilege
- << " current: " << pe.currentLevel
- << " max: " << pe.maxLevel
- );
+ if (!forAdmin) {
+ // All policy entries in PRIVACY_MANAGER should be fully-qualified
+ pe.maxLevel = CynaraAdmin::getInstance().convertToPolicyDescription(
+ CynaraAdmin::getInstance().GetPrivilegeManagerMaxLevel(
+ policy.client, policy.user, policy.privilege));
+ } else {
+ // Cannot reliably calculate maxLavel for policies from ADMIN bucket
+ pe.maxLevel = CynaraAdmin::getInstance().convertToPolicyDescription(CYNARA_ADMIN_ALLOW);
+ }
- policyEntries.push_back(pe);
+
+ LogDebug(
+ "[policy_entry] app: " << pe.appName
+ << " user: " << pe.user
+ << " privilege: " << pe.privilege
+ << " current: " << pe.currentLevel
+ << " max: " << pe.maxLevel
+ );
+
+ policyEntries.push_back(pe);
+ }
};
} catch (const CynaraException::Base &e) {
diff --git a/src/common/smack-labels.cpp b/src/common/smack-labels.cpp
index 73c1b046..55243a8e 100644
--- a/src/common/smack-labels.cpp
+++ b/src/common/smack-labels.cpp
@@ -183,28 +183,35 @@ void setupSharedPrivatePath(const std::string &pkgName, const std::string &path)
pathSetSmack(path.c_str(), generateSharedPrivateLabel(pkgName, path), XATTR_NAME_SMACK);
}
-std::string generateAppNameFromLabel(const std::string &label)
+void generateAppPkgNameFromLabel(const std::string &label, std::string &appName, std::string &pkgName)
{
- static const char prefix[] = "User::App::";
-
- if (label.compare(0, sizeof(prefix) - 1, prefix))
- ThrowMsg(SmackException::InvalidLabel, "Cannot extract appName from Smack label " << label);
-
- std::string ret = label.substr(sizeof(prefix) - 1);
-
- if (ret.size() == 0) {
- ThrowMsg(SmackException::InvalidLabel, "No appName in Smack label " << label);
+ static const char pkgPrefix[] = "User::Pkg::";
+ static const char appPrefix[] = "::App::";
+
+ if (label.compare(0, sizeof(pkgPrefix) - 1, pkgPrefix))
+ ThrowMsg(SmackException::InvalidLabel, "Invalid application process label " << label);
+
+ size_t pkgStartPos = sizeof(pkgPrefix) - 1;
+ size_t pkgEndPos = pkgName.find(appPrefix, pkgStartPos);
+ if (pkgEndPos != std::string::npos) {
+ LogDebug("Hybrid application process label");
+ size_t appStartPos = pkgEndPos + sizeof(appPrefix) - 1;
+ appName = label.substr(appStartPos, std::string::npos);
+ pkgName = label.substr(pkgStartPos, pkgEndPos - pkgStartPos);
+ } else {
+ pkgName = label.substr(pkgStartPos, std::string::npos);
}
- return ret;
+ if (pkgName.empty())
+ ThrowMsg(SmackException::InvalidLabel, "No pkgName in Smack label " << label);
}
std::string generateProcessLabel(const std::string &appName, const std::string &pkgName,
bool isHybrid)
{
- (void)pkgName;
- (void)isHybrid;
- std::string label = "User::App::" + appName;
+ std::string label = "User::Pkg::" + pkgName;
+ if (isHybrid)
+ label += "::App::" + appName;
if (smack_label_length(label.c_str()) <= 0)
ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from appName " << appName);
diff --git a/src/include/app-runtime.h b/src/include/app-runtime.h
index 1d7028ce..133c65ad 100644
--- a/src/include/app-runtime.h
+++ b/src/include/app-runtime.h
@@ -133,6 +133,9 @@ void security_manager_groups_free(char **groups, size_t groups_count);
* If both app_id and pkg_id are NULL then SECURITY_MANAGER_ERROR_INPUT_PARAM will be returned.
* When socket descriptor is incorrect or not related to any package, this function will
* return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT.
+ * If process on the other side is a nonhybrid application, no app_id will be available.
+ *
+ * \note For non hybrid applications only package id can be returned
*
* \param[in] sockfd Socket descriptor of wanted application
* \param[out] pkg_id Package id of the application
@@ -150,10 +153,13 @@ int security_manager_identify_app_from_socket(int sockfd, char **pkg_id, char **
* If both app_id and pkg_id are NULL then SECURITY_MANAGER_ERROR_INPUT_PARAM will be returned.
* When process identifier is incorrect or not related to any package, this function will
* return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT.
+ * If given process is a nonhybrid application, no app_id will be available.
*
* \note Caller must be able to access and read file /proc/PID/atrr/current where PID is the given
* process identifier.
*
+ * \note For non hybrid applications only package id can be returned
+ *
* \param[in] pid Process identifier of wanted application
* \param[out] pkg_id Package id of the application
* \param[out] app_id Application id of the application
@@ -171,6 +177,7 @@ int security_manager_identify_app_from_pid(pid_t pid, char **pkg_id, char **app_
* When process identifier is incorrect or not related to any package, this function will
* return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT.
*
+ * \note For non hybrid applications only package id can be returned
*
* \param[in] client Application Cynara client identifier
* \param[out] pkg_id Package id of the application