Make policy changes affect always entire package 48/207948/5
authorTomasz Swierczek <t.swierczek@samsung.com>
Fri, 14 Jun 2019 06:39:24 +0000 (08:39 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Wed, 19 Jun 2019 10:14:47 +0000 (12:14 +0200)
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
src/common/policy/PkgInfo.h
src/common/policy/Policy.cpp
src/common/policy/Policy.h
src/notification-daemon/Logic.cpp
src/notification-daemon/Logic.h
src/notification-daemon/PolicyUpdater.cpp
src/notification-daemon/PolicyUpdater.h

index 57736239c255a902190b10b611643eee6651eecb..0827f98517c18dc9079750248529d710b8b178aa 100644 (file)
@@ -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<std::string> *output = static_cast<std::vector<std::string>*>(user_data);
+    output->push_back(std::string(appid));
+    return 0;
+}
+
+std::vector<std::string> 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<std::string> 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<std::string>();
+    }
+    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);
index c838ec9c56ae6d8581d620e0cd7995ec8548c756..af225cd2e90002111a173ea93de025fc911b743c 100644 (file)
@@ -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 <string>
 #include <sys/types.h>
+#include <vector>
 
 namespace AskUser {
 
@@ -71,6 +72,8 @@ protected:
 };
 
 class PkgMgrPkgInfo : public PkgInfo {
+public:
+    static std::vector<std::string> listOfAppIds(const std::string &pkgId, uid_t uid);
 protected:
     virtual void fetch(const std::string &pkgId, uid_t uid);
 };
index 94f3bf94beec531384fe53d785e64a8361bd2015..67a87283f15e46f31d8b76a4ab0d754f0b6e9d7e 100644 (file)
@@ -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<PolicyEntryCopy> 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<char, decltype(free)*> 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;
index 5bcfb866b9c93ad172478e2be3338951896ea0ed..3af17fec90fbba4c8602bb8e1a4eaba6dd87b41d 100644 (file)
@@ -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<Privilege> getManifestPrivs(const std::string &appId);
 
index f7b305bbe3b1b27789bdb1351c2691ddc54a1fe8..c2027ef22992bad0841dc01403d1f6ede9ad051c 100644 (file)
@@ -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;
     }
index 5e4a10a02c6aa7875f42f3a851e816c7a5dd54a6..dd7243fa771dc6a1fdd2a893f443ec8ae821f830 100644 (file)
@@ -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 {
index c99ec0592618c9345b19f6cf75fd1a6bd735afbc..068c17fa7544a6dc2d9a3893bcdeff20ac0312bd 100644 (file)
@@ -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.
 #include "PolicyUpdater.h"
 #include <policy/Policy.h>
 #include <policy/PrivilegeInfo.h>
+#include <policy/PkgInfo.h>
 
 namespace AskUser {
 
 namespace Notification {
 
-bool PolicyUpdater::update(const std::string &appId, const std::vector<std::string> &privacies,
+bool PolicyUpdater::update(const std::string &pkgId, const std::string &appId, bool isHybrid,
+                           const std::vector<std::string> &privacies,
                            const std::vector<std::string> &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<std::stri
         static const std::string user = std::to_string(geteuid());
         PolicyRequest req;
 
-        for (size_t i = 0; i < privacies.size(); ++i) {
-            const auto &privacy = privacies[i];
-            const auto &level = levels[i];
+        std::vector<std::string> 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));
             }
         }
 
index 8cc72a90b5aa172a1b7101e347d630794fe2dfa9..15815fe4fde29452ef236c920cb33756515c46bc 100644 (file)
@@ -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<std::string> &privacies,
+    bool update(const std::string &pkgId, const std::string &appId, bool isHybrid,
+                const std::vector<std::string> &privacies,
                 const std::vector<std::string> &levels);
 };