#include <dpl/log/log.h>
#include <dpl/errno_string.h>
-#include <app_manager.h>
#include <sys/smack.h>
#include <config.h>
}
typedef std::map<std::string, std::vector<std::string>> AppsAllowedPrivilegesMap;
-namespace {
-
-struct AppManagerCallbackContext {
- ServiceImpl *impl;
- AppsAllowedPrivilegesMap *appsAllowedPrivileges;
-};
-
-std::string getAppIdFromContext(app_context_h app_context)
+void ServiceImpl::updateRunningAppSmackPolicy(
+ const MountNS::AppContext &appContext,
+ const std::map<std::string, std::vector<std::string>> &appsAllowedPrivileges)
{
- char *appId;
- int ret = app_context_get_app_id (app_context, &appId);
- if (ret != APP_MANAGER_ERROR_NONE) {
- LogError("Failed to get appId from app_context: " << ret);
- return "";
- }
- std::unique_ptr<char, decltype(std::free) *> appIdPtr(appId, std::free);
- std::string appIdStr(appId);
- appIdPtr.release();
- return appIdStr;
-}
+ LogDebug("Updateing privilege Smack policy for: " << appContext.appProcessLabel);
-} // namespace anonymous
-bool ServiceImpl::updateRunningAppSmackPolicy(app_context_h app_context, void *user_data) {
- AppManagerCallbackContext *context = reinterpret_cast<AppManagerCallbackContext*>(user_data);
-
- std::string appId = getAppIdFromContext(app_context);
- if (appId.empty()) {
- LogDebug("No appId from running context");
- return true;
+ auto it = appsAllowedPrivileges.find(appContext.appProcessLabel);
+ if (it == appsAllowedPrivileges.end()) {
+ LogError("No allowed privileges set for " << appContext.appProcessLabel);
+ return;
}
+ auto oldAllowedPrivs = it->second;
- LogDebug("Found " << appId << " running");
-
- std::string pkgName;
- context->impl->getPkgName(appId, pkgName);
-
- bool isPkgHybrid = context->impl->m_privilegeDb.IsPackageHybrid(pkgName);
-
- auto oldAllowedPrivs = context->appsAllowedPrivileges->operator[](appId);
-
- auto it = context->impl->m_appIdUidMap.find(appId);
- if (it == context->impl->m_appIdUidMap.end()) {
- LogError("THIS IS VERY VERY BAD. RUNNING APPLICATION HAS NO SAVED UID!!!");
- return true;
- }
- uid_t uid = it->second;
std::vector<std::string> newAllowedPrivs;
- auto appProcessLabel = SmackLabels::generateProcessLabel(appId, pkgName, isPkgHybrid);
- context->impl->getAppAllowedPrivileges(appProcessLabel, uid, newAllowedPrivs);
+ getAppAllowedPrivileges(appContext.appProcessLabel, appContext.uidStr, newAllowedPrivs);
- std::vector<std::string> inter;
std::sort(oldAllowedPrivs.begin(), oldAllowedPrivs.end());
std::sort(newAllowedPrivs.begin(), newAllowedPrivs.end());
std::set_difference(newAllowedPrivs.begin(), newAllowedPrivs.end(),
oldAllowedPrivs.begin(), oldAllowedPrivs.end(),
std::back_inserter(allowed));
+
+ std::string appName, pkgName;
+ SmackLabels::generateAppPkgNameFromLabel(appContext.appProcessLabel, appName, pkgName);
+
int authorId;
- context->impl->m_privilegeDb.GetPkgAuthorId(pkgName, authorId);
+ m_privilegeDb.GetPkgAuthorId(pkgName, authorId);
- context->impl->m_smackRules.disablePrivilegeRules(appProcessLabel, pkgName, authorId, denied);
- context->impl->m_smackRules.enablePrivilegeRules(appProcessLabel, pkgName, authorId, allowed);
+ m_smackRules.disablePrivilegeRules(appContext.appProcessLabel, pkgName, authorId, denied);
+ m_smackRules.enablePrivilegeRules(appContext.appProcessLabel, pkgName, authorId, allowed);
+}
- return true;
+bool isMultiUser(const MountNS::AppContext &app, const std::vector<MountNS::AppContext> &runningApps)
+{
+ for (auto &runningApp: runningApps) {
+ if (runningApp.appProcessLabel == app.appProcessLabel && runningApp.uidStr != app.uidStr)
+ return true;
+ }
+ return false;
}
int ServiceImpl::policyUpdate(const Credentials &creds, const std::vector<policy_entry> &policyEntries)
std::map<std::string, std::vector<std::string>> appsAllowedPrivileges;
std::vector<std::string> allPackages;
- // TODO: Can this be optimized to: if policy entries contain either wildcard
- // in place of privilege or if any of the privileges has smack mapping?
if (m_smackRules.isPrivilegeMappingEnabled()) {
- // Get policy of all installed application so we can recalculate it after update
- m_privilegeDb.GetAllPackages(allPackages);
- for (auto &package : allPackages) {
- std::vector<std::string> packageApps;
- m_privilegeDb.GetPkgApps(package, packageApps);
- bool isPkgHybrid = m_privilegeDb.IsPackageHybrid(package);
- for (auto &app : packageApps) {
- auto it = m_appIdUidMap.find(app);
- if (it == m_appIdUidMap.end()) {
- // TODO: Move app -> uid mapping to database
- LogDebug("App " << app << " has never been run in security-manager instance");
- continue;
- }
- uid_t uid = it->second;
- auto appProcessLabel = SmackLabels::generateProcessLabel(app, package, isPkgHybrid);
- getAppAllowedPrivileges(appProcessLabel, uid, appsAllowedPrivileges[app]);
- }
+ for (auto &appKnownContext: m_appIdUidMap) {
+ auto appProcessLabel = appKnownContext.first;
+ auto uid = appKnownContext.second;
+
+ getAppAllowedPrivileges(appProcessLabel, uid, appsAllowedPrivileges[appProcessLabel]);
}
}
// Apply updates
if (m_smackRules.isPrivilegeMappingEnabled()) {
LogDebug("Updating privilege related Smack rules");
- AppManagerCallbackContext context{this, &appsAllowedPrivileges};
- int ret = app_manager_foreach_running_app_context(&ServiceImpl::updateRunningAppSmackPolicy,
- &context);
- if (ret != APP_MANAGER_ERROR_NONE) {
- LogError("Failed to update Smack policy for running apps");
+ auto runningApps = MountNS::getMountNSApps();
+ for (auto &appContext : runningApps) {
+ if (isMultiUser(appContext, runningApps)) {
+ LogError("Detected multiuser launch for " << appContext.appProcessLabel
+ << ", policy won't be updated for its context.");
+ } else {
+ try {
+ updateRunningAppSmackPolicy(appContext, appsAllowedPrivileges);
+ } catch (const SmackException::InvalidLabel &e) {
+ LogError("AppContext: " << appContext.appProcessLabel
+ << " doesn't describe an application");
+ }
+ }
}
}
return ret;
}
-
int ServiceImpl::getAppAllowedPrivileges(const Smack::Label &appProcessLabel,
uid_t uid, std::vector<std::string> &allowedPrivileges)
+
+{
+ return getAppAllowedPrivileges(appProcessLabel, std::to_string(uid), allowedPrivileges);
+}
+
+int ServiceImpl::getAppAllowedPrivileges(const Smack::Label &appProcessLabel,
+ const std::string &uid, std::vector<std::string> &allowedPrivileges)
{
try {
LogDebug("Getting allowed privileges for " << appProcessLabel << " and user " << uid);
- std::string uidStr = std::to_string(uid);
std::vector<std::string> privileges;
- m_cynaraAdmin.getAppPolicy(appProcessLabel, uidStr, privileges);
+ m_cynaraAdmin.getAppPolicy(appProcessLabel, uid, privileges);
m_cynaraAdmin.getAppPolicy(appProcessLabel, CYNARA_ADMIN_WILDCARD, privileges);
m_cynaraAdmin.getAppPolicy(CYNARA_ADMIN_WILDCARD, CYNARA_ADMIN_WILDCARD, privileges);
for (auto &privilege : privileges) {
int result = CYNARA_ADMIN_DENY;
std::string resultExtra;
- m_cynaraAdmin.check(appProcessLabel, uidStr, privilege, CynaraAdmin::Buckets[Bucket::PRIVACY_MANAGER], result, resultExtra, true);
+ m_cynaraAdmin.check(appProcessLabel, uid, privilege, CynaraAdmin::Buckets[Bucket::PRIVACY_MANAGER], result, resultExtra, true);
if (result == CYNARA_ADMIN_ALLOW) {
LogDebug("Application " << appProcessLabel << " has " << privilege << " allowed");
allowedPrivileges.push_back(privilege);
return getAppProcessLabel(appName);
}
-struct AppMgrCheckAppsCbContext {
- std::string appName;
- bool isRunning;
-};
-
-bool ServiceImpl::checkRunningApps(app_context_h app_context, void *user_data)
-{
- AppMgrCheckAppsCbContext *context = reinterpret_cast<AppMgrCheckAppsCbContext*>(user_data);
- std::string appId = getAppIdFromContext(app_context);
- if (appId == context->appName) {
- context->isRunning = true;
- return false;
- }
-
- return true;
-}
-
int ServiceImpl::prepareApp(const Credentials &creds, const std::string &appName, const std::vector<std::string> &privPathsVector,
Smack::Label &label, std::string &pkgName, bool &enabledSharedRO,
std::vector<gid_t> &forbiddenGroups, std::vector<gid_t> &allowedGroups, std::vector<bool> &privPathsStatusVector)
if (m_smackRules.isPrivilegeMappingEnabled()) {
uid_t savedUid;
- auto it = m_appIdUidMap.find(appName);
+ auto it = m_appIdUidMap.find(label);
if (it == m_appIdUidMap.end()) {
- m_appIdUidMap[appName] = creds.uid;
+ m_appIdUidMap[label] = creds.uid;
savedUid = creds.uid;
} else {
savedUid = it->second;
if (savedUid != creds.uid) {
LogDebug("Possible second instance detected. Checking all running apps");
- AppMgrCheckAppsCbContext context{appName, false};
- int ret = app_manager_foreach_running_app_context(&ServiceImpl::checkRunningApps,
- &context);
- if (ret != APP_MANAGER_ERROR_NONE) {
- LogError("Couldn't check running apps. No Smack policy will be applied for "
- << appName);
- } else if (context.isRunning) {
- LogError("Application is already running! No Smack policy will be applied for "
- << appName);
- } else {
+ auto runningApps = MountNS::getMountNSApps();
+ auto it = std::find_if(runningApps.begin(), runningApps.end(),
+ [&] (const MountNS::AppContext &app) {
+ return app.appProcessLabel == label;
+ });
+ if (it == runningApps.end()) {
+ LogDebug("Second instance of " << appName << " is not currently running");
+ m_smackRules.enablePrivilegeRules(label, pkgName, authorId, allowedPrivileges);
+ } else if (it->uidStr == std::to_string(creds.uid)){
+ LogWarning("Second instance of " << appName
+ << " detected, but for the same uid as requested");
m_smackRules.enablePrivilegeRules(label, pkgName, authorId, allowedPrivileges);
+ } else {
+ LogWarning("Second instance of " << appName
+ << " detected runnign with " << it->uidStr << ". "
+ << " No privilege related Smack rules will be applied");
}
m_appIdUidMap[appName] = creds.uid;
} else {