From 200d1111174a346c66a7783c21980dfd921fb25e Mon Sep 17 00:00:00 2001 From: Tomasz Swierczek Date: Fri, 14 Jun 2019 08:39:24 +0200 Subject: [PATCH] Make policy changes affect always entire package hybrid apps in a package don't share Smack label, so changes in policy were done individually per each app. This has to be changed to be consistent with entire platform's operation where each package, from end-user perspective, is treated as one entity. Change-Id: I456fe210f788f1fab39c619747bf57544193bae8 --- src/common/policy/PkgInfo.cpp | 34 ++++++++++++++- src/common/policy/PkgInfo.h | 5 ++- src/common/policy/Policy.cpp | 7 +++- src/common/policy/Policy.h | 4 +- src/notification-daemon/Logic.cpp | 9 ++-- src/notification-daemon/Logic.h | 3 +- src/notification-daemon/PolicyUpdater.cpp | 69 +++++++++++++++++++------------ src/notification-daemon/PolicyUpdater.h | 5 ++- 8 files changed, 96 insertions(+), 40 deletions(-) diff --git a/src/common/policy/PkgInfo.cpp b/src/common/policy/PkgInfo.cpp index 5773623..0827f98 100644 --- a/src/common/policy/PkgInfo.cpp +++ b/src/common/policy/PkgInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co. + * Copyright (c) 2018-2019 Samsung Electronics Co. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,6 +46,38 @@ void AulPkgInfo::fetch(const std::string &pkgId, uid_t uid) { m_uid = uid; } +int app_func(pkgmgrinfo_appinfo_h handle, void *user_data) +{ + char *appid = NULL; + int ret = pkgmgrinfo_appinfo_get_appid(handle, &appid); + if (ret != PMINFO_R_OK) { + ALOGE("pkgmgrinfo_appinfo_get_appid failed with " << ret); + return -1; + } + std::vector *output = static_cast*>(user_data); + output->push_back(std::string(appid)); + return 0; +} + +std::vector PkgMgrPkgInfo::listOfAppIds(const std::string &pkgId, uid_t uid) +{ + pkgmgrinfo_pkginfo_h handle = nullptr; + int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle); + std::vector output; + if (ret != PMINFO_R_OK) { + ALOGE("pkgmgrinfo_pkginfo_get_usr_pkginfo failed for " << pkgId << " with " << ret); + return output; + } + ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_ALL_APP, app_func, &output); + if (ret != PMINFO_R_OK) { + ALOGE("pkgmgrinfo_appinfo_get_list failed for " << pkgId << " with " << ret); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return std::vector(); + } + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return output; +} + void PkgMgrPkgInfo::fetch(const std::string &pkgId, uid_t uid) { pkgmgrinfo_pkginfo_h handle = nullptr; int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle); diff --git a/src/common/policy/PkgInfo.h b/src/common/policy/PkgInfo.h index c838ec9..af225cd 100644 --- a/src/common/policy/PkgInfo.h +++ b/src/common/policy/PkgInfo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 Samsung Electronics Co. + * Copyright (c) 2017-2019 Samsung Electronics Co. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ #include #include +#include namespace AskUser { @@ -71,6 +72,8 @@ protected: }; class PkgMgrPkgInfo : public PkgInfo { +public: + static std::vector listOfAppIds(const std::string &pkgId, uid_t uid); protected: virtual void fetch(const std::string &pkgId, uid_t uid); }; diff --git a/src/common/policy/Policy.cpp b/src/common/policy/Policy.cpp index 94f3bf9..67a8728 100644 --- a/src/common/policy/Policy.cpp +++ b/src/common/policy/Policy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 Samsung Electronics Co. + * Copyright (c) 2016-2019 Samsung Electronics Co. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,7 +128,7 @@ std::vector getAppPolicy(const std::string &appId) { return fetch.fetchPolicy(); } -void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId) +void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId, bool &isHybrid) { char *pkgName = nullptr; char *appName = nullptr; @@ -138,6 +138,9 @@ void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId std::unique_ptr app_name_p(appName, free); throwOnSMError("security_manager_identify_app_from_cynara_client", ret); + // if the appId was in Smack label of client, it means that the app comes from hybrid package + isHybrid = (appName == nullptr ? false : true); + if (!pkgName) { ALOGE("Couldn't identify clients package id"); return; diff --git a/src/common/policy/Policy.h b/src/common/policy/Policy.h index 5bcfb86..3af17fe 100644 --- a/src/common/policy/Policy.h +++ b/src/common/policy/Policy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 Samsung Electronics Co. + * Copyright (c) 2016-2019 Samsung Electronics Co. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ namespace AskUser { class PolicyEntryCopy; std::string getOwnAppId(PkgInfo &pkgInfo); -void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId); +void identifyApp(PkgInfo &pkgInfo, const std::string &client, std::string &appId, std::string &pkgId, bool &isHybrid); std::set getManifestPrivs(const std::string &appId); diff --git a/src/notification-daemon/Logic.cpp b/src/notification-daemon/Logic.cpp index f7b305b..c2027ef 100644 --- a/src/notification-daemon/Logic.cpp +++ b/src/notification-daemon/Logic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 Samsung Electronics Co. + * Copyright (c) 2017-2019 Samsung Electronics Co. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -109,12 +109,13 @@ void Logic::addChannelFd(Protocol::ConnectionFd fd, const Protocol::Credentials std::string appId, pkgId; PkgMgrPkgInfo pkgInfo; - identifyApp(pkgInfo, creds.label, appId, pkgId); + bool isHybrid; + identifyApp(pkgInfo, creds.label, appId, pkgId, isHybrid); ALOGD("Proper client connected"); stopTimer(); - ConnectionInfo connInfo{appId, pkgId, creds.uid}; + ConnectionInfo connInfo{appId, pkgId, creds.uid, isHybrid}; m_connToInfo.insert(it, std::make_pair(fd, connInfo)); } catch (const std::exception &e) { ALOGE("Failed to add channel fd " << fd); @@ -423,7 +424,7 @@ bool Logic::setPolicy(const ConnectionInfo &conn) { levels[i] = clientResponseToPolicy(currentEvent.privacyResponses[privacy]); } - if (!PolicyUpdater::update(conn.appId, currentEvent.uniquePrivacies, levels)) { + if (!PolicyUpdater::update(conn.pkgId, conn.appId, conn.isHybrid, currentEvent.uniquePrivacies, levels)) { ALOGE("Couldn't set policy for " << conn.appId); return false; } diff --git a/src/notification-daemon/Logic.h b/src/notification-daemon/Logic.h index 5e4a10a..dd7243f 100644 --- a/src/notification-daemon/Logic.h +++ b/src/notification-daemon/Logic.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 Samsung Electronics Co. + * Copyright (c) 2017-2019 Samsung Electronics Co. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,7 @@ private: std::string appId; std::string pkgId; std::string user; + bool isHybrid; }; struct PrivilegeStruct { diff --git a/src/notification-daemon/PolicyUpdater.cpp b/src/notification-daemon/PolicyUpdater.cpp index c99ec05..068c17f 100644 --- a/src/notification-daemon/PolicyUpdater.cpp +++ b/src/notification-daemon/PolicyUpdater.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2019 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,16 +29,19 @@ #include "PolicyUpdater.h" #include #include +#include namespace AskUser { namespace Notification { -bool PolicyUpdater::update(const std::string &appId, const std::vector &privacies, +bool PolicyUpdater::update(const std::string &pkgId, const std::string &appId, bool isHybrid, + const std::vector &privacies, const std::vector &levels) { try { - ALOGD("Generating policy update for: app: " << appId << ", user:" << geteuid() + uid_t myUid = geteuid(); + ALOGD("Generating policy update for: app: " << appId << ", hybrid: " << isHybrid << ", user:" << myUid << ", privacies num: " << privacies.size()); if (privacies.size() != levels.size() || levels.size() == 0) { @@ -49,34 +52,46 @@ bool PolicyUpdater::update(const std::string &appId, const std::vector appIds = {appId}; - ALOGD("Generating policy update for: app: " << appId << ", user:" << geteuid() - << ", privacy " << privacy << ", level: " << level); + if (isHybrid) { + // apps in a hybrid package have distinct Smack labels; + // since entire platform manages privileges per package, + // here we need to get all apps in the pkg for the policy + // to be effective for entire pkg + appIds = PkgMgrPkgInfo::listOfAppIds(pkgId, myUid); + } - auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacy); - if (privacyPrivs.empty()) { - ALOGE("Unable to get privacy privileges for privacy " << privacy); - throw Exception("Unable to get privacy privileges for privacy " + privacy); - } + for (auto &app : appIds) { + for (size_t i = 0; i < privacies.size(); ++i) { + const auto &privacy = privacies[i]; + const auto &level = levels[i]; + + ALOGD("Generating policy update for: app: " << app << ", user:" << geteuid() + << ", privacy " << privacy << ", level: " << level); + + auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacy); + if (privacyPrivs.empty()) { + ALOGE("Unable to get privacy privileges for privacy " << privacy); + throw Exception("Unable to get privacy privileges for privacy " + privacy); + } - for (auto &priv : privacyPrivs) { - std::string currentPolicy = getPrivilegePolicy(appId, priv); - if (currentPolicy.empty()) { - ALOGD("Application didn't request privilege " << priv << ", skipping"); - continue; + for (auto &priv : privacyPrivs) { + std::string currentPolicy = getPrivilegePolicy(app, priv); + if (currentPolicy.empty()) { + ALOGD("Application didn't request privilege " << priv << ", skipping"); + continue; + } + ALOGD("Adding policy entries for : app: " << app << ", priv: " + << priv << ", user:" << user << ", level: " + << level); + PolicyEntry entry; + entry.setApp(app); + entry.setUser(user); + entry.setPrivilege(priv); + entry.setLevel(level); + req.addEntry(std::move(entry)); } - ALOGD("Adding policy entries for : app: " << appId << ", priv: " - << priv << ", user:" << user << ", level: " - << level); - PolicyEntry entry; - entry.setApp(appId); - entry.setUser(user); - entry.setPrivilege(priv); - entry.setLevel(level); - req.addEntry(std::move(entry)); } } diff --git a/src/notification-daemon/PolicyUpdater.h b/src/notification-daemon/PolicyUpdater.h index 8cc72a9..15815fe 100644 --- a/src/notification-daemon/PolicyUpdater.h +++ b/src/notification-daemon/PolicyUpdater.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 - 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,8 @@ namespace AskUser { namespace Notification { namespace PolicyUpdater { - bool update(const std::string &appId, const std::vector &privacies, + bool update(const std::string &pkgId, const std::string &appId, bool isHybrid, + const std::vector &privacies, const std::vector &levels); }; -- 2.7.4