Remove privilege related Smack rules when multi-user is detected 70/230070/6
authorZofia Abramowska <z.abramowska@samsung.com>
Tue, 7 Apr 2020 17:12:55 +0000 (19:12 +0200)
committerZofia Abramowska <z.abramowska@samsung.com>
Mon, 20 Apr 2020 10:56:56 +0000 (12:56 +0200)
Privilege related Smack rules can only be used, when applications
can be launched for only one user. When multiple instances of
one application for different users are detected, all privilege
related Smack rules for this application will be revoked.
This isn't a permanent state. When application is launched only
for one user it will acquire all needed permissions.

Change-Id: Ibda63d3ce4ce072f48fff4ff0e2c083c69fe66d7

src/common/include/service_impl.h
src/common/service_impl.cpp

index ff98d51083f747a34081e1d72e93480e45acd8a4..7e63ba37acf0c4925646283719c8c9d17b1f8ec5 100644 (file)
@@ -443,6 +443,8 @@ private:
                               const std::string &path);
 
     static bool updateRunningAppSmackPolicy(app_context_h app_context, void *user_data);
+    static bool checkRunningApps(app_context_h app_context, void *user_data);
+
     void updatePermissibleSet(uid_t uid, int type);
 
     Smack::Label getAppProcessLabel(const std::string &appName, const std::string &pkgName);
index a1c145a73b3152a8381e55023ea32168c0693247..5308991cdef05bf2ee758f3822ae957f9957064f 100644 (file)
@@ -2254,6 +2254,23 @@ Smack::Label ServiceImpl::getProcessLabel(const std::string &appName)
     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)
@@ -2279,10 +2296,39 @@ int ServiceImpl::prepareApp(const Credentials &creds, const std::string &appName
     getPkgLabels(pkgName, pkgLabels);
 
     if (m_smackRules.isPrivilegeMappingEnabled()) {
-        m_appIdUidMap[appName] = creds.uid;
+        uid_t savedUid;
+        auto it = m_appIdUidMap.find(appName);
+        if (it == m_appIdUidMap.end()) {
+            m_appIdUidMap[appName] = creds.uid;
+            savedUid = creds.uid;
+        } else {
+            savedUid = it->second;
+        }
 
+        // We have to remove all possible privilege related Smack rules, because application
+        // policy might have changed from last prepareApp
+        // (e.g. application new version was installed)
         m_smackRules.disableAllPrivilegeRules(label, pkgName, authorId);
-        m_smackRules.enablePrivilegeRules(label, pkgName, authorId, allowedPrivileges);
+
+        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 {
+                m_smackRules.enablePrivilegeRules(label, pkgName, authorId, allowedPrivileges);
+            }
+            m_appIdUidMap[appName] = creds.uid;
+        } else {
+            m_smackRules.enablePrivilegeRules(label, pkgName, authorId, allowedPrivileges);
+        }
     }
 
     ret = getForbiddenAndAllowedGroups(label, allowedPrivileges, forbiddenGroups,