Remove unused shared ro template
[platform/core/test/security-tests.git] / src / security-manager-tests / common / sm_commons.cpp
index 86e02f1..7e5f52a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 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.
  *    limitations under the License.
  */
 
+#include <algorithm>
 #include <cstring>
+#include <fcntl.h>
 #include <ftw.h>
 #include <grp.h>
 #include <string>
 #include <sys/capability.h>
+#include <sys/prctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <unordered_map>
+#include <cstdlib>
+
+#include <array>
 #include <unordered_set>
+#include <utility>
 #include <vector>
 
 #include <security-manager-types.h>
+#include <app-runtime.h>
 #include <sys/smack.h>
+#include <privilege_info.h>
+#include <scoped_process_label.h>
 
 #include <cynara_test_client.h>
 #include <dpl/test/test_runner.h>
 #include <memory.h>
 #include <sm_api.h>
 #include <sm_commons.h>
-#include <sm_db.h>
+#include <synchronization_pipe.h>
 #include <sm_request.h>
 #include <tests_common.h>
+#include <policy_configuration.h>
 #include "tzplatform.h"
+#include <label_generator.h>
+#include <template_parser.h>
+#include <temp_test_user.h>
 
 using namespace SecurityManagerTest;
 
-// Common const values
-
-const privileges_t SM_ALLOWED_PRIVILEGES = {
-    "http://tizen.org/privilege/display",
-    "http://tizen.org/privilege/nfc"
-};
-
-const privileges_t SM_DENIED_PRIVILEGES  = {
-    "http://tizen.org/privilege/bluetooth",
-    "http://tizen.org/privilege/power"
-};
-
-const privileges_t SM_NO_PRIVILEGES  = {
-};
-
-const std::vector<std::string> SM_ALLOWED_GROUPS = {"db_browser", "db_alarm"};
-
-const std::string uidToStr(const uid_t uid)
-{
-    return std::to_string(static_cast<unsigned int>(uid));
-}
-
-// Common implementation details
-
-std::string generateAppLabel(const std::string &appId)
-{
-    return "User::App::" + appId;
-}
-
-std::string generatePkgLabel(const std::string &pkgId)
-{
-    return "User::Pkg::" + pkgId;
-}
-
-static std::string genPath(int app_num, const char *postfix) {
-    char buf[16];
-    sprintf(buf, "%02d", app_num);
-    return std::string("/opt/usr/apps/sm_test_") + std::string(buf) + std::string("_pkg_id_full/") + std::string(postfix);
-}
-
-std::string genRWPath(int app_num) {
-    return genPath(app_num, "app_dir");
-}
-std::string genROPath(int app_num) {
-    return genPath(app_num, "app_dir_ro");
-}
-std::string genPublicROPath(int app_num) {
-    return genPath(app_num, "app_dir_public_ro");
-}
+#define CONF_DIR "/usr/share/security-manager/policy/"
+#define SMACK_RULES_PATH "/sys/fs/smackfs/load2"
 
-std::string genOwnerRWOthersROPath(int app_num) {
-    return genPath(app_num, "app_dir_rw_others_ro");
-}
-
-static std::string generatePkgLabelOwnerRWothersRO(const std::string &pkgId)
-{
-    return "User::Pkg::" + pkgId + "::SharedRO";
-}
+#define ALLOW 0
+#define DENY -1
 
 // Common DB/nftw checks
 
@@ -189,16 +151,6 @@ int nftw_check_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/,
     return 0;
 }
 
-static int nftw_set_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/,
-                                int /*typeflag*/, struct FTW* /*ftwbuf*/)
-{
-    smack_lsetlabel(fpath, "canary_label", SMACK_LABEL_ACCESS);
-    smack_lsetlabel(fpath, "canary_label", SMACK_LABEL_EXEC);
-    smack_lsetlabel(fpath, nullptr, SMACK_LABEL_TRANSMUTE);
-
-    return 0;
-}
-
 int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
                        int /*typeflag*/, struct FTW* /*ftwbuf*/)
 {
@@ -209,14 +161,12 @@ int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
     return 0;
 }
 
-static const char *const SM_DENIED_PATH = "/opt/usr/apps/non_app_dir";
-
-void check_app_permissions(const char *const app_id, const char *const pkg_id,
-                           const char *const user, const privileges_t &allowed_privs,
-                           const privileges_t &denied_privs)
+void check_app_permissions(const std::string &app_id, const std::string &pkg_id,
+                           const std::string &user, const privileges_t &allowed_privs,
+                           const privileges_t &denied_privs, bool isHybrid)
 {
     (void) pkg_id;
-    std::string smackLabel = generateAppLabel(app_id);
+    std::string smackLabel = generateProcessLabel(app_id, pkg_id, isHybrid);
 
     CynaraTestClient::Client ctc;
 
@@ -229,14 +179,117 @@ void check_app_permissions(const char *const app_id, const char *const pkg_id,
     }
 }
 
+void sm_app_has_privileges(const AppInstallHelper &app,
+                           const std::vector<std::string> &privileges,
+                           int expectedResult)
+{
+    for (auto const &privilege : privileges) {
+        int result;
+        Api::appHasPrivilege(app.getAppId(), privilege, app.getUID(), result);
+        RUNNER_ASSERT_MSG(result == expectedResult, "Application " << app.getAppId()
+                          << " has unexpected access to " << privilege << ", is : "
+                          << " should be : " << expectedResult );
+    }
+}
+
+static void check_app_smack_accesses(const std::string &appId, const std::string &pkgId,
+                                     bool isHybrid = false)
+{
+    static const std::vector<AccessRequest> rules[] =
+        {parseSmackRulesFile(CONF_DIR "pkg-rules-template.smack"),
+         parseSmackRulesFile(CONF_DIR "app-rules-template.smack")};
+
+    const std::pair<std::string, std::string> switchAliases[] =
+        {std::make_pair("~PATH_RW~", generatePathRWLabel(pkgId)),
+         std::make_pair("~PATH_RO~", generatePathROLabel(pkgId)),
+         std::make_pair("~PROCESS~", generateProcessLabel(appId, pkgId, isHybrid))};
+
+    for (auto rule : rules[isHybrid]) {
+        if (rule.object == "~PATH_TRUSTED~") {
+            continue;
+        }
+
+        for (const auto &alias : switchAliases) {
+            if (rule.subject == alias.first) {
+                rule.subject = alias.second;
+            }
+            if (rule.object == alias.first) {
+                rule.object = alias.second;
+            }
+        }
+
+        if (rule.object == "_") {
+            rule.access = "rx" + rule.access;
+        }
+
+        check_exact_smack_accesses(rule.subject, rule.object, rule.access);
+    }
+}
 
-void check_app_after_install(const char *const app_id, const char *const pkg_id)
+static void assert_no_label_in_rule(const AccessRequest &rule, const std::string &label)
 {
-    TestSecurityManagerDatabase dbtest;
-    dbtest.test_db_after__app_install(app_id, pkg_id);
+    RUNNER_ASSERT_MSG(rule.object != label && rule.subject != label,
+                      "Smack rule left after uninstallation process." <<
+                      " Subject: " << rule.subject <<
+                      " object: " << rule.object <<
+                      " access: " << rule.access);
 }
 
-static void check_app_gids(const char *const app_id, const std::vector<gid_t> &allowed_gids)
+static void check_pkg_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
+{
+    const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
+    const std::string labels[] = {generatePathRWLabel(pkgId),
+                                  generatePathROLabel(pkgId),
+                                  generateProcessLabel(appId, pkgId, true),
+                                  generateProcessLabel(appId, pkgId)};
+    for (const auto &rule : rules) {
+        for (const auto &label : labels) {
+            assert_no_label_in_rule(rule, label);
+        }
+    }
+}
+
+static void check_hybrid_app_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
+{
+    const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
+    const std::string appLabel = generateProcessLabel(appId, pkgId, true);
+    for (const auto &rule : rules) {
+        assert_no_label_in_rule(rule, appLabel);
+    }
+}
+
+static void check_app(const std::string &appId, const std::string &pkgId,
+                      bool shouldBeInstalled, bool isHybrid, bool removePkg)
+{
+    char *retPkgId;
+    int ret = security_manager_get_app_pkgid(&retPkgId, appId.c_str());
+
+    if (shouldBeInstalled) {
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "The given appId is not installed.");
+
+        if (ret == SECURITY_MANAGER_SUCCESS) {
+            CStringPtr retPkgIdPtr(retPkgId);
+            RUNNER_ASSERT_MSG(strcmp(pkgId.c_str(), retPkgId) == 0,
+                              "The given appId does not belong to the given pkgId.");
+        }
+        check_app_smack_accesses(appId, pkgId, isHybrid);
+    } else {
+        RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "The given appId is installed.");
+
+        if (removePkg) {
+            check_pkg_smack_rules_after_uninstall(appId, pkgId);
+        } else if (isHybrid) {
+            check_hybrid_app_smack_rules_after_uninstall(appId, pkgId);
+        }
+    }
+}
+
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id, bool isHybrid)
+{
+    check_app(app_id, pkg_id, true, isHybrid, false);
+}
+
+static void check_app_gids(const std::string &app_id, const std::vector<gid_t> &allowed_gids)
 {
     int ret;
     gid_t main_gid = getgid();
@@ -266,25 +319,21 @@ static void check_app_gids(const char *const app_id, const std::vector<gid_t> &a
 
 static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/
 
-void check_app_after_install(const char *const app_id, const char *const pkg_id,
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
                              const privileges_t &allowed_privs,
                              const privileges_t &denied_privs,
-                             const std::vector<std::string> &allowed_groups)
+                             bool isHybrid)
 {
-    TestSecurityManagerDatabase dbtest;
-    dbtest.test_db_after__app_install(app_id, pkg_id);
+    check_app(app_id, pkg_id, true, isHybrid, false);
+    /* Privileges should be granted to all users if root installs app */
+    check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs, isHybrid);
 
-    /*Privileges should be granted to all users if root installs app*/
-    check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs);
-
-    /* Setup mapping of gids to privileges */
-    /* Do this for each privilege for extra check */
-    for (const auto &privilege : allowed_privs) {
-        dbtest.setup_privilege_groups(privilege, allowed_groups);
-    }
+    PolicyConfiguration policy;
+    const PolicyConfiguration::GroupVector allowed_groups = policy.privToGroup(allowed_privs);
+    RUNNER_ASSERT_MSG(allowed_groups.size() == allowed_privs.size(),
+                      "Some privileges given were not found in the policy");
 
     std::vector<gid_t> allowed_gids;
-
     for (const auto &groupName : allowed_groups) {
         errno = 0;
         struct group* grp = getgrnam(groupName.c_str());
@@ -295,106 +344,67 @@ void check_app_after_install(const char *const app_id, const char *const pkg_id,
     check_app_gids(app_id, allowed_gids);
 }
 
-void check_path(const std::string &path, const std::string &label) {
+void check_path(const std::string &path, const std::string &label, bool transmute, bool execute) {
     nftw_expected_label = label;
-    nftw_expected_transmute = true;
-    nftw_expected_exec = false;
+    nftw_expected_transmute = transmute;
+    nftw_expected_exec = execute;
 
     // check labels
     int result = nftw(path.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
     RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path);
 }
 
-void check_app_path_after_install(int app_num, const char *pkgId, bool others_enabled)
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+                               bool isHybrid, bool removePkg)
 {
-    std::string SM_RW_PATH = genRWPath(app_num);
-    std::string SM_RO_PATH = genROPath(app_num);
-    std::string SM_PUBLIC_RO_PATH = genPublicROPath(app_num);
-    int result;
-
-    nftw_expected_label = generatePkgLabel(pkgId);
-    nftw_expected_transmute = true;
-    nftw_expected_exec = false;
-
-    result = nftw(SM_RW_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_RW_PATH);
-
-    nftw_expected_label = generatePkgLabel(pkgId) + "::RO";
-    nftw_expected_transmute = false;
-    nftw_expected_exec = false;
-
-    result = nftw(SM_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_RO_PATH);
-
-    nftw_expected_label = "User::Home";
-    nftw_expected_transmute = true;
-    nftw_expected_exec = false;
-
-    result = nftw(SM_PUBLIC_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_PUBLIC_RO_PATH);
-
-    result = nftw(SM_DENIED_PATH, &nftw_check_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_DENIED_PATH);
-
-    // owner RW, others RO
-    if(others_enabled) {
-        std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(app_num);
-        nftw_expected_label = generatePkgLabelOwnerRWothersRO(pkgId);
-        nftw_expected_transmute = true;
-        nftw_expected_exec = false;
-
-        result = nftw(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
-        RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_OWNER_RW_OTHERS_RO_PATH);
-    }
-}
-
-void check_app_after_uninstall(const char *const app_id, const char *const pkg_id,
-                               const bool is_pkg_removed)
-{
-    TestSecurityManagerDatabase dbtest;
-    dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed);
+    check_app(app_id, pkg_id, false, isHybrid, removePkg);
 }
 
-void check_app_after_uninstall(const char *const app_id, const char *const pkg_id,
-                               const privileges_t &privileges, const bool is_pkg_removed)
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+                               const privileges_t &privileges, bool isHybrid,
+                               bool removePkg)
 {
-    TestSecurityManagerDatabase dbtest;
-    dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed);
+    check_app(app_id, pkg_id, false, isHybrid, removePkg);
 
-
-    /*Privileges should not be granted anymore to any user*/
-    check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, SM_NO_PRIVILEGES, privileges);
+    /* Privileges should not be granted anymore to any user */
+    check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, {}, privileges, isHybrid);
 }
 
-static void prepare_app_path(int app_num, bool others_enabled = false)
-{
-    std::string SM_RW_PATH = genRWPath(app_num);
-    std::string SM_RO_PATH = genROPath(app_num);
-    std::string SM_PUBLIC_RO_PATH = genPublicROPath(app_num);
-    int result;
-
-    result = nftw(SM_RW_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_RW_PATH);
-
-    result = nftw(SM_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_RO_PATH);
-
-    result = nftw(SM_PUBLIC_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_PUBLIC_RO_PATH);
-
-    if(others_enabled) {
-        std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(app_num);
-        result = nftw(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
-        RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_OWNER_RW_OTHERS_RO_PATH);
+std::string access_opposite(std::string &access) {
+    static const std::map<char, int> access_mapping = {{'r', 0}, {'w', 1}, {'x', 2}, {'a', 3},
+                                                       {'t', 4}, {'l', 5}};
+    // May write implies may lock
+    if (access.find('w') != std::string::npos && access.find('l') == std::string::npos) {
+        access.append("l");
+    }
+    std::string access_opposite = "rwxatl";
+    for (char c : access) {
+        access_opposite[access_mapping.at(c)] = '-';
+    }
+    auto it = std::remove_if(access_opposite.begin(), access_opposite.end(), [](char c) {return c == '-';});
+    access_opposite.erase(it, access_opposite.end());
+    return access_opposite;
+}
+
+void check_exact_smack_accesses(const std::string &subject, const std::string &object,
+                                const std::string &access) {
+    std::string access_str(access);
+    auto no_access = access_opposite(access_str);
+    for (char c : access_str) {
+        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
+                          << ">, <" << c << "> errno=" << strerror(errno));
+        RUNNER_ASSERT_MSG(ret == 1, "Access " << c << " from " << subject << " to "
+                          << object << " not given");
     }
 
-    result = nftw(SM_DENIED_PATH, &nftw_set_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
-    RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << SM_DENIED_PATH);
-}
-
-void prepare_app_env(int app_num, bool others_enabled)
-{
-    prepare_app_path(app_num, others_enabled);
+    for (char c : no_access) {
+        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object
+                          << ">, <" << c << "> errno=" << strerror(errno));
+        RUNNER_ASSERT_MSG(ret == 0, "Access " << c << " from " << subject << " to "
+                          << object << " unnecessarily given");
+    }
 }
 
 CapsSetsUniquePtr setCaps(const char *cap_string)
@@ -407,97 +417,127 @@ CapsSetsUniquePtr setCaps(const char *cap_string)
     return caps;
 }
 
-void install_app(const char *app_id, const char *pkg_id, uid_t uid, app_install_type type,
-                 bool check_after)
-{
-    InstallRequest request;
-    request.setAppId(app_id);
-    request.setPkgId(pkg_id);
-    request.setUid(uid);
-    if (type != SM_APP_INSTALL_NONE)
-        request.setInstallType(type);
-    Api::install(request);
-
-    if (check_after)
-        check_app_after_install(app_id, pkg_id);
+static int getOppositeAccessType(int accessType) {
+    return accessType ^ (R_OK | W_OK | X_OK);
 }
 
-void uninstall_app(const char *app_id, const char *pkg_id, bool expect_pkg_removed,
-                   app_install_type type, bool check_after)
+static const std::unordered_map<int, const char* const> accessTypeToString {
+    std::make_pair(0, "F_OK"),
+    std::make_pair(1, "X_OK"),
+    std::make_pair(2, "W_OK"),
+    std::make_pair(3, "W_OK|X_OK"),
+    std::make_pair(4, "R_OK"),
+    std::make_pair(5, "R_OK|X_OK"),
+    std::make_pair(6, "R_OK|W_OK"),
+    std::make_pair(7, "R_OK|W_OK|X_OK")
+};
+
+void accessCheck(const std::string &id, const std::string &path, int accessType,
+                 int expected)
 {
-    InstallRequest request;
-    request.setAppId(app_id);
-    if (type != SM_APP_INSTALL_NONE)
-        request.setInstallType(type);
-    Api::uninstall(request);
+    RUNNER_ASSERT_MSG(::access(path.c_str(), accessType) == expected,
+                      "access from " << id << " to path " << path
+                       << (expected == 0 ? " not granted" : " unnecessarily granted")
+                       << " (" << accessTypeToString.at(accessType) << ")");
+}
+
+void accessTest(const std::string &id, const std::string &testPath, int accessType) {
+    int oppositeAccessType = getOppositeAccessType(accessType);
 
-    if (check_after)
-        check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed);
+    if (accessType != 0) {
+        accessCheck(id, testPath, accessType, ALLOW);
+    }
+    if (oppositeAccessType != 0) {
+        static const std::vector<int> singleAccessTypes = {R_OK, W_OK, X_OK};
+        for (auto singleAccessType : singleAccessTypes) {
+            if (oppositeAccessType & singleAccessType) {
+                accessCheck(id, testPath, singleAccessType, DENY);
+            }
+        }
+    }
 }
 
-static const std::string EXEC_FILE("exec");
-static const std::string NORMAL_FILE("normal");
-static const std::string LINK_PREFIX("link_to_");
+void runAccessTest(const std::string &label, uid_t uid, gid_t gid,
+                   const std::string &testPath, int accessType) {
+    auto fun = [&](){
+        ScopedProcessLabel spl(label, false);
+        RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(uid, gid),
+                                "drop_root_privileges failed.");
 
-static void createTestDir(const std::string &dir)
-{
-    mode_t dirMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
-    mode_t execFileMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
-    mode_t normalFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+        accessTest(label, testPath, accessType);
+    };
 
-    mktreeSafe(dir, dirMode);
-    creatSafe(dir + "/" + EXEC_FILE, execFileMode);
-    creatSafe(dir + "/" + NORMAL_FILE, normalFileMode);
-    symlinkSafe(dir + "/" + EXEC_FILE, dir + "/" + LINK_PREFIX + EXEC_FILE);
-    symlinkSafe(dir + "/" + NORMAL_FILE, dir + "/" + LINK_PREFIX + NORMAL_FILE);
+    runInChildParentWait(fun);
 }
 
-static void createInnerAppDir(const std::string &dir, const std::string &nonAppDir)
-{
-    createTestDir(dir);
+void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType) {
+    auto fun = [&](){
+        Api::setProcessLabel(app.getAppId());
+        RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(app.getUID(), app.getGID()),
+                                "drop_root_privileges failed.");
+        accessTest(app.getAppId(), testPath, accessType);
+    };
 
-    symlinkSafe(nonAppDir, dir + "/" + LINK_PREFIX + "non_app_dir");
-    symlinkSafe(nonAppDir + "/" + EXEC_FILE,
-                dir + "/" + LINK_PREFIX + "non_app_" + EXEC_FILE);
-    symlinkSafe(nonAppDir + "/" + NORMAL_FILE,
-                dir + "/" + LINK_PREFIX + "non_app_" + NORMAL_FILE);
+    runInChildParentWait(fun);
 }
 
-static const std::string nonAppDirPath(const TemporaryTestUser &user)
-{
-    return TMP_DIR + "/" + user.getUserName();
+static const std::vector<std::string> SM_SYSTEM_LABELS = {"System", "System::Privileged", "User"};
+
+void runSystemAccessTest(uid_t uid, gid_t gid, const std::string &testPath, int accessType) {
+    for (const auto &label : SM_SYSTEM_LABELS)
+        runAccessTest(label, uid, gid, testPath, accessType);
 }
 
-static void generateAppDir(const TemporaryTestUser &user,
-       const std::string &appId, const std::string &pkgId)
-{
-    const std::string dir = TzPlatformConfig::appDirPath(user, appId, pkgId);
-    const std::string nonAppDir = nonAppDirPath(user);
+bool isAskuserDisabled() {
+    static bool isAskuserDisabled = false;
+    static bool isChecked = false;
+
+    if (isChecked)
+        return isAskuserDisabled;
 
-    createInnerAppDir(dir, nonAppDir);
-    createInnerAppDir(dir + "/.inner_dir", nonAppDir);
-    createInnerAppDir(dir + "/inner_dir", nonAppDir);
+    std::string sysShare = TzPlatformConfig::getPath(TZ_SYS_SHARE);
+    std::string askDisableFile = sysShare + "/askuser_disable";
+
+    isAskuserDisabled = (access(askDisableFile.c_str(), F_OK) != -1);
+    isChecked = true;
+    return isAskuserDisabled;
 }
 
-static void generateNonAppDir(const TemporaryTestUser &user)
-{
-    const std::string dir = nonAppDirPath(user);
+bool isPrivilegePrivacy(const std::string &priv) {
+    return (1 == privilege_info_is_privacy(priv.c_str()));
+}
 
-    createTestDir(dir);
-    createTestDir(dir + "/.inner_dir");
-    createTestDir(dir + "/inner_dir");
+int countPrivacyPrivileges(const PrivilegeVector &privs) {
+    return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy);
 }
 
-void createTestDirs(const TemporaryTestUser &user,
-                    const std::string &appId, const std::string &pkgId)
-{
-    generateAppDir(user, appId, pkgId);
-    generateNonAppDir(user);
+int countPrivacyPrivileges(const std::vector<std::string> &privs) {
+    return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy);
 }
 
-void removeTestDirs(const TemporaryTestUser &user,
-                    const std::string &appId, const std::string &pkgId)
+int setLauncherSecurityAttributes(uid_t uid, gid_t gid)
+{
+    // Add launcher capabilities (cap_dac_override, cap_setgid, cap_sys_admin, cap_mac_admin),
+    // launcher is user process, we must drop root privileges (cap_setgid, cap_setuid are needed).
+    // By default, the permitted capability set is cleared when credentials change is made
+    // (if a process drops a capability from its permitted set, it can never reacquire that capability),
+    // setting the "keep capabilities" flag prevents it from being cleared.
+    // Effective capability set is always cleared when credential change is made, we need to add them again.
+
+    setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep cap_setuid+ep");
+    int ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0);
+    if (ret != 0)
+        return ret;
+
+    ret = drop_root_privileges(uid, gid);
+    if (ret != 0)
+        return ret;
+
+    setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep");
+    return ret;
+}
+int setLauncherSecurityAttributes(TemporaryTestUser &user)
 {
-    removeDir(TzPlatformConfig::appDirPath(user, appId, pkgId));
-    removeDir(nonAppDirPath(user));
+    return setLauncherSecurityAttributes(user.getUid(), user.getGid());
 }
+