From: Filip Skrzeczkowski Date: Wed, 29 Jan 2025 19:35:09 +0000 (+0100) Subject: Implement security_manager_get_app_owner_uid for no-smack tizen X-Git-Tag: accepted/tizen/unified/20250217.155039~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ce7c971d54b8729bbad7e6f11ae5705d7823cad8;p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git Implement security_manager_get_app_owner_uid for no-smack tizen Test with security_manager_26_1_security_manager_get_app_owner_uid in no-smack mode. Change-Id: I5890289df072f5113caba8231aa125a332a48dd8 --- diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp index 1de09f9b..c19c29e4 100644 --- a/src/client/client-security-manager.cpp +++ b/src/client/client-security-manager.cpp @@ -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 diff --git a/src/common/include/privilege_db.h b/src/common/include/privilege_db.h index 7c205235..b37b2e09 100644 --- a/src/common/include/privilege_db.h +++ b/src/common/include/privilege_db.h @@ -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 * diff --git a/src/common/include/protocols.h b/src/common/include/protocols.h index c11f7dc7..064fdb7e 100644 --- a/src/common/include/protocols.h +++ b/src/common/include/protocols.h @@ -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, diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h index 714477e9..13ba6319 100644 --- a/src/common/include/service_impl.h +++ b/src/common/include/service_impl.h @@ -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. diff --git a/src/common/privilege_db.cpp b/src/common/privilege_db.cpp index 12df7c10..3428fd43 100644 --- a/src/common/privilege_db.cpp +++ b/src/common/privilege_db.cpp @@ -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, [&] { diff --git a/src/common/protocols.cpp b/src/common/protocols.cpp index 5aabc56c..5da2a05c 100644 --- a/src/common/protocols.cpp +++ b/src/common/protocols.cpp @@ -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); diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp index 1f35f2fd..7ba8cfdc 100644 --- a/src/common/service_impl.cpp +++ b/src/common/service_impl.cpp @@ -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); diff --git a/src/include/app-runtime.h b/src/include/app-runtime.h index 64770d08..5e851064 100644 --- a/src/include/app-runtime.h +++ b/src/include/app-runtime.h @@ -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 diff --git a/src/server/service/include/service.h b/src/server/service/include/service.h index c0527b41..f48b9684 100644 --- a/src/server/service/include/service.h +++ b/src/server/service/include/service.h @@ -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 * diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp index 0bcc4d71..595d8a18 100644 --- a/src/server/service/service.cpp +++ b/src/server/service/service.cpp @@ -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;