/*
- * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2020 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 <unordered_map>
#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 <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;
-#define SMACK_RULES_PATH "/sys/fs/smackfs/load2"
-
#define ALLOW 0
#define DENY -1
return 0;
}
-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 = generateProcessLabel(app_id, pkg_id, isHybrid);
-
- CynaraTestClient::Client ctc;
-
- for (auto &priv : allowed_privs) {
- ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_ALLOWED);
- }
-
- for (auto &priv : denied_privs) {
- ctc.check(smackLabel.c_str(), "", user, priv.c_str(), CYNARA_API_ACCESS_DENIED);
- }
-}
-
-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(PolicyConfiguration::getPkgRulesFilePath()),
- parseSmackRulesFile(PolicyConfiguration::getAppRulesFilePath())};
-
- 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);
- }
-}
-
-static void assert_no_label_in_rule(const AccessRequest &rule, const std::string &label)
-{
- 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_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();
- std::unordered_set<gid_t> reference_gids(allowed_gids.begin(), allowed_gids.end());
-
- // Reset supplementary groups
- ret = setgroups(0, NULL);
- RUNNER_ASSERT_MSG(ret != -1, "Unable to set supplementary groups");
-
- Api::setProcessGroups(app_id);
-
- ret = getgroups(0, nullptr);
- RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
-
- std::vector<gid_t> actual_gids(ret);
- ret = getgroups(ret, actual_gids.data());
- RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
-
- for (const auto &gid : actual_gids) {
- RUNNER_ASSERT_MSG(gid == main_gid || reference_gids.count(gid) > 0,
- "Application shouldn't get access to group " << gid);
- reference_gids.erase(gid);
- }
-
- RUNNER_ASSERT_MSG(reference_gids.empty(), "Application didn't get access to some groups");
-}
-
-static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/
-
-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,
- bool isHybrid)
-{
- 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);
-
- 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());
- RUNNER_ASSERT_ERRNO_MSG(grp, "Group: " << groupName << " not found");
- allowed_gids.push_back(grp->gr_gid);
- }
-
- check_app_gids(app_id, allowed_gids);
-}
-
void check_path(const std::string &path, const std::string &label, bool transmute, bool execute) {
nftw_expected_label = label;
nftw_expected_transmute = transmute;
RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path);
}
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
- bool isHybrid, bool removePkg)
-{
- check_app(app_id, pkg_id, false, isHybrid, removePkg);
-}
-
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
- const privileges_t &privileges, bool isHybrid,
- bool removePkg)
-{
- 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, {}, privileges, isHybrid);
-}
-
-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");
- }
-
- 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)
{
CapsSetsUniquePtr caps(cap_init());