Calculate application privilege level based on manifest data passed by installer 94/240694/4
authorTomasz Swierczek <t.swierczek@samsung.com>
Mon, 10 Aug 2020 12:22:35 +0000 (14:22 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Tue, 1 Sep 2020 11:18:17 +0000 (11:18 +0000)
privilege-checker soon will need the cert-level information to calculate
application privilege attributes (blacklisted or privacy).

This cert-level will be, in target solution, passed as installation argument to
install request (see commit eb065339daf1ed9b091add719128f64e2372fd0e).

However, because that API was only recently introduced,
simply storing this data in security-manager.db at app install time and then
reusing it at userInit stage will not do the trick in a FOTA scenario (userInit
called after a FOTA where some apps are already in the DB).

Preparing a new DB field and running a migration script to calculate that field could
be a solution to the problem, but it would require additional sql query to get
application privilege-level inside implementation of userInit routine.

Alternative solution, exercised by this patch, is to rely on the installer,
which seems to be always adding the:

http://tizen.org/privilege/internal/default/[public | partner | platform]

privileges to install request, depending on the actual privilege level of package.

Since CynaraAdmin::userInit already has the global manifest bucket listed in memory,
there's no need for additional DB fetch - only one more iteration over the list to get
the highest privilege level available for given app.

Change-Id: Ib860e7f4d09e7f434197ddc08ae3777a119734d0

src/common/cynara.cpp

index c374763e234d5936ef4d67253d0074cf4664ffb5..fcb6baa5831e400106210c320e1ac1fa95f56be1 100644 (file)
@@ -35,6 +35,7 @@
 #include <config.h>
 #include <utils.h>
 #include <privilege-info.h>
+#include <security-manager-types.h>
 #include <lm-config.h>
 
 namespace SecurityManager {
@@ -570,11 +571,29 @@ void CynaraAdmin::userInit(uid_t uid, security_manager_user_type userType)
         }
     }
 
+    // installer adds these privilege(s) to each applications' manifest data at install stage
+    // to indicate cert-level; privilege checker will need this information to check privilege
+    // attribute
+    std::map<std::string, int> appToCertLevel;
+    for (CynaraAdminPolicy &policy : appPolicies) {
+        std::string appName(policy.client);
+        if (appToCertLevel.find(appName) == appToCertLevel.end())
+            appToCertLevel[appName] = SM_PKG_PRIVILEGE_LEVEL_NONE;
+        if (strcmp(policy.privilege, "http://tizen.org/privilege/internal/default/public") == 0)
+            appToCertLevel[appName] = max(appToCertLevel[appName], SM_PKG_PRIVILEGE_LEVEL_PUBLIC);
+        else if (strcmp(policy.privilege, "http://tizen.org/privilege/internal/default/partner") == 0)
+            appToCertLevel[appName] = max(appToCertLevel[appName], SM_PKG_PRIVILEGE_LEVEL_PARTNER);
+        else if (strcmp(policy.privilege, "http://tizen.org/privilege/internal/default/platform") == 0)
+            appToCertLevel[appName] = SM_PKG_PRIVILEGE_LEVEL_PLATFORM;
+    }
+
     // for each global app: retrieve its privacy-related abnd blacklist privileges and set
     // their policy in PRIVACY_MANAGER bucket accordingly
     for (CynaraAdminPolicy &policy : appPolicies) {
         try {
-            PrivilegeInfo priv(uid, policy.client, policy.privilege);
+            PrivilegeInfo priv(uid, policy.client, policy.privilege,
+                SM_PKG_TYPE_NONE,
+                appToCertLevel[policy.client]);
             if (askUserEnabled && priv.hasAttribute(PrivilegeInfo::PrivilegeAttr::PRIVACY))
                 policies.push_back(CynaraAdminPolicy(
                         policy.client,