Add setup of /run/user/<uid> for dynamically added users 87/321287/4
authorTomasz Swierczek <t.swierczek@samsung.com>
Tue, 18 Mar 2025 08:58:00 +0000 (09:58 +0100)
committerTomasz Swierczek <t.swierczek@samsung.com>
Thu, 20 Mar 2025 09:27:36 +0000 (10:27 +0100)
Added remembering which users have their /run/user/<uid>
directory already setup & in case its not, proper chmod is added
to logic of prepare_app server-side call.

This way we don't need to modify upstream systemd & don't need to add
separate unit listening on contents of /run/user/ directory
for newly created user entries.

Reference: permissions for newly created user are configured
by systemd here:

https://review.tizen.org/gerrit/gitweb?p=platform/upstream/systemd.git;a=blob;f=src/login/user-runtime-dir.c;hb=f2effd148a8337259d6efd0499d678e6fb52da46#l52

Change-Id: I67fa019a9006e0bbe900f4e1a0c16af83c8a1d22

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

index d69452fa89a886c6a60c2929c94a53deb95319ae..0b8636120227925955423fb89674d33f390fbdfd 100644 (file)
@@ -30,6 +30,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 
+#include <mutex>
+#include <unordered_set>
 #include <vector>
 
 #include "channel.h"
@@ -524,9 +526,11 @@ private:
 
     int getAppDefinedPrivilegeDescription(uid_t uid, const std::string &privilege, std::string &appName, std::string &pkgName, std::string &license);
 
-    void setupAccessToRunUserDir(uid_t uid);
+    bool setupAccessToRunUserDir(uid_t uid);
 
     // Objects below have to be accessed under a mutex each time - need to be thread safe at usage
+    std::unordered_set<uid_t> m_runUserUidsConfigured;
+    std::mutex m_runUserUidMutex;
     Cynara m_cynara;            // added api mutex
     SmackRules m_smackRules;    // seems to work out of the box, assuming that libsmack can be used from many threads at once
     PrivilegeDb m_privilegeDb;  // added api mutex -> if one thread only does RW ScopedTransactions (from service_impl), its okay
index 713593673c76b4ae58d7444ad8c777845b002ee0..759ee26f505e44c30010416bc75fc8f1020afbad 100644 (file)
@@ -209,11 +209,13 @@ ServiceImpl::ServiceImpl(Offline offline) :
             // would have ie. one common group and ACL should be configured to give ccess to the /run/user/<ID>
             // path for that group. Proper solution would probably include modifications around systemd
             // or adding separate service for doing that before security-manager starts setting up
-            // user processes with PUIDs, also dynamic addition of new users has to be considered just in case.
+            // user processes with PUIDs.
             std::vector<uid_t> listOfUsers;
             m_cynaraAdmin.listUsers(listOfUsers);
+
             for (auto &uid : listOfUsers)
-                setupAccessToRunUserDir(uid);
+                if (setupAccessToRunUserDir(uid))
+                    m_runUserUidsConfigured.insert(uid);
         }
     }
 }
@@ -226,7 +228,7 @@ ServiceImpl::ServiceImpl(Offline offline) :
 // root:/run/user> ls -lZ
 // total 0
 // drwxr-x--- 8 owner system_share * 260 Feb 14 18:37 5001
-void ServiceImpl::setupAccessToRunUserDir(uid_t uid)
+bool ServiceImpl::setupAccessToRunUserDir(uid_t uid)
 {
     try {
         std::string path = TizenPlatformConfig::makePath(TZ_SYS_RUN, "user", std::to_string(uid));
@@ -234,15 +236,18 @@ void ServiceImpl::setupAccessToRunUserDir(uid_t uid)
         struct stat statbuf;
         if (stat(path.c_str(), &statbuf) == -1) {
             LogErrno("Error getting file status on path: " << path);
-            return;
+            return false;
         }
         other_mode |= statbuf.st_mode;
         if (-1 == chmod(path.c_str(), other_mode)) {
             LogErrno("Error in setting up /run/user/<uid> path for path: " << path << "  - chmod failed!");
+            return false;
         }
     } catch (...) {
         LogError("Error in setting up /run/user/<uid> path for uid: " << uid);
+        return false;
     }
+    return true;
 }
 
 int ServiceImpl::validatePolicy(const Credentials &creds, policy_entry &policyEntry, CynaraAdminPolicy &cyap)
@@ -1324,6 +1329,10 @@ int ServiceImpl::userDelete(const Credentials &creds, uid_t uidDeleted)
 
     m_cynaraAdmin.userRemove(uidDeleted);
 
+    if (!smack_simple_check()) {
+        std::lock_guard<std::mutex> lock(m_runUserUidMutex);
+        m_runUserUidsConfigured.erase(uidDeleted);
+    }
     return ret;
 }
 typedef std::map<std::string, std::vector<std::string>> AppsAllowedPrivilegesMap;
@@ -2750,6 +2759,13 @@ int ServiceImpl::prepareApp(const Credentials &creds, const std::string &appName
             gid_t authorsGId;
             if (m_privilegeDb.GetAuthorGId(pkgName, authorsGId))
                 allowedGroups.emplace_back(authorsGId);
+
+            std::lock_guard<std::mutex> lock(m_runUserUidMutex);
+            if (m_runUserUidsConfigured.find(creds.uid) == m_runUserUidsConfigured.end()) {
+                LogWarning("App launched for uid " << creds.uid << ", need to configure access to /run/user/<UID>");
+                if (setupAccessToRunUserDir(creds.uid))
+                    m_runUserUidsConfigured.insert(creds.uid);
+            }
         }
 
         std::vector<std::string> allowedPrivileges;