Implement security_manager_get_app_owner_uid for no-smack tizen 75/318875/41
authorFilip Skrzeczkowski <f.skrzeczkow@samsung.com>
Wed, 29 Jan 2025 19:35:09 +0000 (20:35 +0100)
committerFilip Skrzeczkowski <f.skrzeczkow@samsung.com>
Fri, 14 Feb 2025 16:06:26 +0000 (16:06 +0000)
Test with security_manager_26_1_security_manager_get_app_owner_uid in no-smack mode.

Change-Id: I5890289df072f5113caba8231aa125a332a48dd8

src/client/client-security-manager.cpp
src/common/include/privilege_db.h
src/common/include/protocols.h
src/common/include/service_impl.h
src/common/privilege_db.cpp
src/common/protocols.cpp
src/common/service_impl.cpp
src/include/app-runtime.h
src/server/service/include/service.h
src/server/service/service.cpp

index 1de09f9be1521c17c37e738cb7893193f9368db5..c19c29e4aec42bb829c9aeda32155ad0d8d71551 100644 (file)
@@ -1881,15 +1881,44 @@ int security_manager_get_app_owner_uid(pid_t pid, uid_t *uid)
 {
     if (!uid)
         return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+
+    uid_t puid;
     struct stat st;
-    std::string path = "/proc/" + std::to_string(pid) + "/";
+    std::string path;
+    try {
+        path = "/proc/" + std::to_string(pid) + "/";
+    }
+    catch(const std::exception& e)
+    {
+        LogError("Path string allocation exception: " << e.what());
+        return SECURITY_MANAGER_ERROR_MEMORY;
+    }
+
     int ret = stat(path.c_str(), &st);
     if (ret < 0) {
         LogError("Access to " << path << " failed with : " << ret);
         return SECURITY_MANAGER_ERROR_UNKNOWN;
     }
-    *uid = st.st_uid;
-    return SECURITY_MANAGER_SUCCESS;
+    puid = st.st_uid;
+
+    if (smack_simple_check()) {
+        *uid = puid;
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
+    uid_t ownerId;
+    using namespace SecurityManager;
+    return try_catch([&]() -> int {
+        ClientRequest request(SecurityModuleCall::APP_GET_OWNER);
+        request.send(puid);
+        if (!request.failed()) {
+            request.recv(ownerId);
+            LogInfo("Received ownerId: " << ownerId << " for app PID " << pid);
+            *uid = ownerId;
+        }
+
+        return request.getStatus();
+    });
 }
 
 SECURITY_MANAGER_API
index 7c2052357450731ccba9d0a5e88cdfdc87ac6b63..b37b2e099a6d22b75340aafecee79e3714f2387d 100644 (file)
@@ -55,6 +55,7 @@ enum class StmtType : uint8_t {
     ERemoveApplication,
     EPkgNameExists,
     EAppNameExists,
+    EGetAppOwner,
     EGetAppPkgName,
     EGetAppPkgInfo,
     EGetAppVersion,
@@ -250,6 +251,17 @@ public:
      */
     bool AuthorExists(const std::string &authorHash);
 
+    /**
+     * Return the uid of and application's owner given its puid
+     *
+     * @param puid - the puid identifying the application
+     * @param[out] ownerId - return application's owner's id
+     * @exception PrivilegeDb::Exception::InternalError on internal error
+     * @exception PrivilegeDb::Exception::ConstraintError on constraint violation
+     * @return true if owner is found in the database
+     */
+    bool GetAppOwner(uid_t puid, uid_t &ownerId);
+
     /**
      * Return package id associated with a given application id
      *
index c11f7dc7e8d90a2b0e2673256e42535185ad1676..064fdb7e2a5c6d107f6d6484a47f38ea4e474bd1 100644 (file)
@@ -135,6 +135,7 @@ enum class SecurityModuleCall
     APP_INSTALL,
     APP_UPDATE,
     APP_UNINSTALL,
+    APP_GET_OWNER,
     APP_GET_PKG_NAME,
     APP_APPLY_PRIVATE_SHARING,
     APP_DROP_PRIVATE_SHARING,
index 714477e95219fff42a7d92c22c5b39a392efe863..13ba6319225ab53c33c5d3a711750b69243d767e 100644 (file)
@@ -102,6 +102,17 @@ public:
     */
     int appUninstall(const Credentials &creds, app_inst_req &req);
 
+    /**
+    * Process a request to get an application's owner uid.
+    * Retrieves the uid of and application's owner given its puid.
+    *
+    * @param[in] puid application process identifier
+    * @param[out] ownerId returned application owner uid
+    *
+    * @return API return code, as defined in protocols.h
+    */
+    int getAppOwner(uid_t puid, uid_t &ownerId);
+
     /**
     * Process package id query.
     * Retrieves the package id associated with given application id.
index 12df7c108c4834ad73af08335b21e7a3bc08a208..3428fd43a857cdbf5b67fa70d28d7e71233eb8b8 100644 (file)
@@ -54,6 +54,7 @@ constexpr const char *g_queries[StmtTypeCount] = {
     [underlying(StmtType::ERemoveApplication)] = "DELETE FROM user_app_pkg_view WHERE app_name=? AND uid=?",
     [underlying(StmtType::EPkgNameExists)] = "SELECT count(*) FROM pkg WHERE name=?",
     [underlying(StmtType::EAppNameExists)] = "SELECT count(*) FROM app WHERE name=?",
+    [underlying(StmtType::EGetAppOwner)] = "SELECT uid, sum(is_hybrid) FROM user_app_pkg_view WHERE (is_hybrid = 1 AND app_id = ?) OR (is_hybrid = 0 AND pkg_id = ?) GROUP BY uid",
     [underlying(StmtType::EGetAppPkgName)] = "SELECT pkg_name FROM user_app_pkg_view WHERE app_name = ?",
     [underlying(StmtType::EGetAppPkgInfo)] = "SELECT pkg.name, pkg.is_hybrid, pkg.shared_ro FROM app, pkg WHERE app.name = ? AND app.pkg_id = pkg.pkg_id",
     [underlying(StmtType::EGetAppVersion)] = "SELECT version FROM app WHERE name = ?",
@@ -246,6 +247,37 @@ bool PrivilegeDb::AppNameExists(const std::string &appName)
     });
 }
 
+bool PrivilegeDb::GetAppOwner(uid_t puid, uid_t &ownerId)
+{
+    return try_catch_db(m_api_mutex, [&] {
+        auto command = getStatement(StmtType::EGetAppOwner);
+        command->BindInteger(1, puid);
+        command->BindInteger(2, puid);
+
+        if (command->Step())
+            ownerId = command->GetColumnInteger(0);
+        else {
+            LogError("Could not find an owner UID for the PUID given: " << puid);
+            return false;
+        }
+
+        // Check how many hybrid apps with the same owner UID and PUID there are.
+        // In case there is more than 1, an error must have occured.
+        int hybridSum = command->GetColumnInteger(1);
+        if (hybridSum > 1)
+            ThrowMsg(PrivilegeDb::Exception::InternalError,
+            "More than 1 hybrid app with given PUID found");
+
+        // Check the next rows.
+        // There should not be any more entries with the same PUID but a diferent owner UID.
+        if (command->Step())
+            ThrowMsg(PrivilegeDb::Exception::InternalError,
+            "More than 1 owner UID found for the app with given PUID");
+
+        return true;
+    });
+}
+
 void PrivilegeDb::GetAppPkgName(const std::string &appName, std::string &pkgName)
 {
     return try_catch_db(m_api_mutex, [&] {
index 5aabc56c60d4d754b39be87141f57730397cd553..5da2a05c4ee637ee7f01d474d22b00b2a0d51712 100644 (file)
@@ -38,6 +38,7 @@ const char * SecurityModuleCallToString(SecurityModuleCall call_num) {
         SM_CODE_DESCRIBE(SecurityModuleCall::APP_INSTALL);
         SM_CODE_DESCRIBE(SecurityModuleCall::APP_UPDATE);
         SM_CODE_DESCRIBE(SecurityModuleCall::APP_UNINSTALL);
+        SM_CODE_DESCRIBE(SecurityModuleCall::APP_GET_OWNER);
         SM_CODE_DESCRIBE(SecurityModuleCall::APP_GET_PKG_NAME);
         SM_CODE_DESCRIBE(SecurityModuleCall::APP_APPLY_PRIVATE_SHARING);
         SM_CODE_DESCRIBE(SecurityModuleCall::APP_DROP_PRIVATE_SHARING);
index 1f35f2fd8ae5e3b24371cd9b47d8c19e3e4456a2..7ba8cfdc92d1610578fb42268f97c6fa39181b52 100644 (file)
@@ -1106,6 +1106,23 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &req)
     return SECURITY_MANAGER_SUCCESS;
 }
 
+int ServiceImpl::getAppOwner(uid_t puid, uid_t &ownerId)
+{
+    try {
+        if (!m_privilegeDb.GetAppOwner(puid, ownerId)) {
+            LogWarning("Application with uid: " << puid << " not found in database");
+            return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+        } else {
+            LogDebug("ownerId: " << ownerId);
+        }
+    } catch (const PrivilegeDb::Exception::Base &e) {
+        LogError("Error while getting ownerId from database: " << e.DumpToString());
+        return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+    }
+
+    return SECURITY_MANAGER_SUCCESS;
+}
+
 int ServiceImpl::getPkgName(const std::string &appName, std::string &pkgName)
 {
     LogDebug("appName: " << appName);
index 64770d08111a212387c62a76d6555338259749f0..5e851064e7f853bb0550c484efc079f5da75c747 100644 (file)
@@ -227,7 +227,8 @@ int security_manager_self_is_app(bool *app);
 int security_manager_is_app_from_pid(pid_t pid, bool *app);
 
 /**
- * Return the UID of the user for which the app was launched
+ * Return the UID of the user for which the app was installed.
+ * Only in No-Smack mode does this function check if the PID is an actual app.
  *
  * \param[out]  uid the user ID of application user
  * \return SECURITY_MANAGER_SUCCESS or error code
index c0527b41afb9eb9bafae5cf063e6925fbdca2328..f48b9684b79970d70b1fb691f3c57eb09d705d68 100644 (file)
@@ -115,6 +115,13 @@ private:
      */
     void processAppUninstall(MessageBuffer &buffer, const Credentials &creds);
 
+    /**
+     * Process getting owner uid identifier from an app puid
+     *
+     * @param buffer Input/output message buffer
+     */
+    void processGetAppOwner(MessageBuffer &buffer);
+
     /**
      * Process getting package identifier from an app identifier
      *
index 0bcc4d71ad41c4a7aa17a8165d81c3ed3f193697..595d8a181ab1fb3a963d3007cd015c25b2e69b15 100644 (file)
@@ -79,6 +79,10 @@ void Service::processEvent(Event &&msg)
                 LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL");
                 processAppUninstall(msg.buffer, msg.creds);
                 break;
+            case SecurityModuleCall::APP_GET_OWNER:
+                LogDebug("call_type: SecurityModuleCall::APP_GET_OWNER");
+                processGetAppOwner(msg.buffer);
+                break;
             case SecurityModuleCall::APP_GET_PKG_NAME:
                 LogDebug("call_type: SecurityModuleCall::APP_GET_PKG_NAME");
                 processGetPkgName(msg.buffer);
@@ -234,6 +238,19 @@ void Service::processAppUninstall(MessageBuffer &buffer, const Credentials &cred
     Serialization::Serialize(buffer, m_serviceImpl.appUninstall(creds, req));
 }
 
+void Service::processGetAppOwner(MessageBuffer &buffer)
+{
+    uid_t puid;
+    uid_t ownerUid;
+
+    Deserialization::Deserialize(buffer, puid);
+    int ret = m_serviceImpl.getAppOwner(puid, ownerUid);
+    buffer.ModeStreaming();
+    Serialization::Serialize(buffer, ret);
+    if (ret == SECURITY_MANAGER_SUCCESS)
+        Serialization::Serialize(buffer, ownerUid);
+}
+
 void Service::processGetPkgName(MessageBuffer &buffer)
 {
     std::string appName;