Test with security_manager_26_1_security_manager_get_app_owner_uid in no-smack mode.
Change-Id: I5890289df072f5113caba8231aa125a332a48dd8
{
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
ERemoveApplication,
EPkgNameExists,
EAppNameExists,
+ EGetAppOwner,
EGetAppPkgName,
EGetAppPkgInfo,
EGetAppVersion,
*/
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
*
APP_INSTALL,
APP_UPDATE,
APP_UNINSTALL,
+ APP_GET_OWNER,
APP_GET_PKG_NAME,
APP_APPLY_PRIVATE_SHARING,
APP_DROP_PRIVATE_SHARING,
*/
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.
[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 = ?",
});
}
+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, [&] {
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);
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);
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
*/
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
*
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);
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;