From f0a2aa867cc0966d57bb8071c17cf68988ca28ac Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Fri, 29 Jan 2016 16:49:13 +0100 Subject: [PATCH] [SM] Apply/drop sharing tests Change-Id: I21e89b450726efef8041d128c4a2221e8dc7009e --- src/security-manager-tests/CMakeLists.txt | 1 + .../common/app_install_helper.h | 36 +- src/security-manager-tests/common/sm_api.cpp | 14 + src/security-manager-tests/common/sm_api.h | 3 + src/security-manager-tests/common/sm_db.cpp | 15 + src/security-manager-tests/common/sm_db.h | 4 + .../common/sm_sharing_request.cpp | 87 ++++ .../common/sm_sharing_request.h | 57 ++ .../security_manager_tests.cpp | 571 +++++++++++++++++++++ 9 files changed, 784 insertions(+), 4 deletions(-) create mode 100644 src/security-manager-tests/common/sm_sharing_request.cpp create mode 100644 src/security-manager-tests/common/sm_sharing_request.h diff --git a/src/security-manager-tests/CMakeLists.txt b/src/security-manager-tests/CMakeLists.txt index 0f50b8e..c408eea 100644 --- a/src/security-manager-tests/CMakeLists.txt +++ b/src/security-manager-tests/CMakeLists.txt @@ -44,6 +44,7 @@ SET(SEC_MGR_SOURCES ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_api.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_db.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_request.cpp + ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_sharing_request.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_user_request.cpp ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_policy_request.cpp ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp diff --git a/src/security-manager-tests/common/app_install_helper.h b/src/security-manager-tests/common/app_install_helper.h index c79d263..a89db84 100644 --- a/src/security-manager-tests/common/app_install_helper.h +++ b/src/security-manager-tests/common/app_install_helper.h @@ -36,6 +36,13 @@ struct AppInstallHelper { return getInstallDir() + "/trustedDir" + std::to_string(i); } + std::string getPrivateDir() { + return getInstallDir() + "/app_dir/"; + } + + std::string getSharedPath(int i = 0) { + return getPrivateDir() + "shareme" + std::to_string(i); + } std::string getAppId() { return m_name + "_app_id"; } @@ -45,11 +52,26 @@ struct AppInstallHelper { } void createInstallDir() { - mkdir(getInstallDir().c_str(), 0777); + if (mkdir(getInstallDir().c_str(), 0777) == 0) { + m_dirs.push_back(getInstallDir()); + } } void createTrustedDir(int i = 0) { - mkdir(getTrustedDir(i).c_str(), 0777); + if (mkdir(getTrustedDir(i).c_str(), 0777) == 0) { + m_dirs.push_back(getTrustedDir(i)); + } + } + void createPrivateDir() { + if (mkdir(getPrivateDir().c_str(), 0777) == 0) { + m_dirs.push_back(getPrivateDir()); + } + } + + void createSharedFile(int i = 0) { + if (creat(getSharedPath(i).c_str(), 0777) == 0) { + m_files.push_back(getSharedPath(i)); + } } void revokeRules() { @@ -71,11 +93,17 @@ struct AppInstallHelper { virtual ~AppInstallHelper() { // TODO we should also remove trusted dirs created with custom params - rmdir(getTrustedDir().c_str()); - rmdir(getInstallDir().c_str()); + for (const auto &dir : m_dirs) { + rmdir(dir.c_str()); + } + for (const auto &file : m_files) { + unlink(file.c_str()); + } } protected: std::string m_name; + std::vector m_dirs; + std::vector m_files; }; diff --git a/src/security-manager-tests/common/sm_api.cpp b/src/security-manager-tests/common/sm_api.cpp index 2e79f1b..604b171 100644 --- a/src/security-manager-tests/common/sm_api.cpp +++ b/src/security-manager-tests/common/sm_api.cpp @@ -176,6 +176,20 @@ void getPolicy(const PolicyEntry &filter, std::vector &policyEntrie }; } +void applySharing(const SharingRequest &req, lib_retcode expectedResult) { + int result = security_manager_private_sharing_apply(req.get()); + RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult, + "Unexpected result from security_manager_private_sharing_apply" << std::endl + << " Result: " << result << ";"); +} + +void dropSharing(const SharingRequest &req, lib_retcode expectedResult) { + int result = security_manager_private_sharing_drop(req.get()); + RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult, + "Unexpected result from security_manager_private_sharing_drop" << std::endl + << " Result: " << result << ";"); +} + void getPolicyForSelf(const PolicyEntry &filter, std::vector &policyEntries, lib_retcode expectedResult) { getConfiguredPolicy(filter, policyEntries, expectedResult, false); diff --git a/src/security-manager-tests/common/sm_api.h b/src/security-manager-tests/common/sm_api.h index e96e249..2a3711b 100644 --- a/src/security-manager-tests/common/sm_api.h +++ b/src/security-manager-tests/common/sm_api.h @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -45,6 +46,8 @@ void getPrivilegesMappings(const char *version_from, const std::vector &privileges, std::vector &mappings, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); +void applySharing(const SharingRequest &req, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); +void dropSharing(const SharingRequest &req, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); } // namespace Api } // namespace SecurityManagerTest diff --git a/src/security-manager-tests/common/sm_db.cpp b/src/security-manager-tests/common/sm_db.cpp index 7eb6f3f..d09703d 100644 --- a/src/security-manager-tests/common/sm_db.cpp +++ b/src/security-manager-tests/common/sm_db.cpp @@ -263,3 +263,18 @@ int64_t TestSecurityManagerDatabase::get_author_id(const std::string &authorName return id; } +std::string TestSecurityManagerDatabase::get_path_label(const std::string &path) +{ + Sqlite3DBaseSelectResult result; + std::ostringstream sql; + if (!m_base.is_open()) + m_base.open(); + sql.clear(); + sql.str("SELECT path_label FROM shared_path WHERE path=\"" + path + "\""); + m_base.execute(sql.str(), result); + + if(result.rows.empty()) + return ""; + + return result.rows[0][0]; +} diff --git a/src/security-manager-tests/common/sm_db.h b/src/security-manager-tests/common/sm_db.h index da71fbe..454996e 100644 --- a/src/security-manager-tests/common/sm_db.h +++ b/src/security-manager-tests/common/sm_db.h @@ -170,6 +170,10 @@ public: * @brief Method for getting author id from database. */ int64_t get_author_id(const std::string &authorName); +/** + * @brief Method for path label from database. + */ + std::string get_path_label(const std::string &path); private: /** * @var base diff --git a/src/security-manager-tests/common/sm_sharing_request.cpp b/src/security-manager-tests/common/sm_sharing_request.cpp new file mode 100644 index 0000000..3e361ec --- /dev/null +++ b/src/security-manager-tests/common/sm_sharing_request.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +namespace SecurityManagerTest { + +SharingRequest::SharingRequest() + : m_req(nullptr) +{ + int result = security_manager_private_sharing_req_new(&m_req); + RUNNER_ASSERT_MSG((lib_retcode)result == SECURITY_MANAGER_SUCCESS, + "creation of new request failed. Result: " << result); + RUNNER_ASSERT_MSG(m_req != nullptr, "creation of new request did not allocate memory"); +} + +SharingRequest::~SharingRequest() +{ + security_manager_private_sharing_req_free(m_req); +} + +void SharingRequest::setOwnerAppId(const std::string &appId, lib_retcode expectedResult) +{ + int result = security_manager_private_sharing_req_set_owner_appid(m_req, appId.c_str()); + RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult, + "setting app id returned wrong value." + << " App id: " << appId << ";" + << " Result: " << result << ";" + << " Expected result: " << expectedResult); + m_appId = appId; +} + +void SharingRequest::setTargetAppId(const std::string &appId, lib_retcode expectedResult) +{ + int result = security_manager_private_sharing_req_set_target_appid(m_req, appId.c_str()); + RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult, + "setting app id returned wrong value." + << " App id: " << appId << ";" + << " Result: " << result << ";" + << " Expected result: " << expectedResult); + m_appId = appId; +} + +void SharingRequest::addPaths(const char **paths, size_t pathCount, lib_retcode expectedResult) +{ + int result = security_manager_private_sharing_req_add_paths(m_req, paths, pathCount); + RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult, + "adding path returned wrong value." + << " Result: " << result << ";" + << " Expected result: " << expectedResult); + for (size_t i = 0; i < pathCount; i++) { + m_paths.push_back(paths[i]); + } +} + +std::ostream& operator<<(std::ostream &os, const SharingRequest &request) +{ + + os << "app id: " << request.m_appId << "; "; + os << "pkg id: " << request.m_pkgId << "; "; + + if (!request.m_paths.empty()) { + os << "paths: [ " << "< " << request.m_paths[0] << ">"; + for (size_t i=1; i < request.m_paths.size(); ++i) { + os << "; < " << request.m_paths[i] << ">"; + } + os << " ]"; + } + return os; +} + +} // namespace SecurityManagerTest diff --git a/src/security-manager-tests/common/sm_sharing_request.h b/src/security-manager-tests/common/sm_sharing_request.h new file mode 100644 index 0000000..e7f4107 --- /dev/null +++ b/src/security-manager-tests/common/sm_sharing_request.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SECURITY_MANAGER_TEST_SHARINGREQUEST +#define SECURITY_MANAGER_TEST_SHARINGREQUEST + +#include +#include +#include +#include +#include + +#include + +namespace SecurityManagerTest { + +class SharingRequest +{ +public: + SharingRequest(); + SharingRequest(const SharingRequest&) = delete; + SharingRequest& operator=(const SharingRequest&) = delete; + ~SharingRequest(); + + void setOwnerAppId(const std::string &appId, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS); + void setTargetAppId(const std::string &pkgId, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS); + void addPaths(const char **paths, size_t path_count, + lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); + const private_sharing_req *get() const { return m_req; } + friend std::ostream& operator<<(std::ostream &, const SharingRequest&); + +private: + private_sharing_req *m_req; + + std::string m_appId; + std::string m_pkgId; + std::vector m_paths; +}; + +std::ostream& operator<<(std::ostream &os, const SecurityManagerTest::SharingRequest &request); + +} // namespace SecurityManagerTest + +#endif // SECURITY_MANAGER_TEST_SHARINGREQUEST diff --git a/src/security-manager-tests/security_manager_tests.cpp b/src/security-manager-tests/security_manager_tests.cpp index 417561c..e01fe67 100644 --- a/src/security-manager-tests/security_manager_tests.cpp +++ b/src/security-manager-tests/security_manager_tests.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,7 @@ #include #include #include +#include "memory.h" using namespace SecurityManagerTest; @@ -499,6 +501,41 @@ void check_exact_access(const std::string& subject, const std::string& object, c } } +std::string access_opposite(std::string &access) { + static const std::map 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"); + } +} + + RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER) @@ -2759,6 +2796,540 @@ RUNNER_TEST(security_manager_27p_API30_app_uninstall) }; } +namespace { +const char *const owner_access = "rwxat"; +const char *const target_path_access = "rxl"; +const char *const target_dir_access = "x"; +const char *const no_access = ""; + +void check_system_access(const std::string pathLabel, bool apply = true) { + check_exact_smack_accesses("User", pathLabel, (apply ? owner_access : no_access)); + check_exact_smack_accesses("System", pathLabel, (apply ? owner_access : no_access)); +} + +void check_owner_access(const std::string &ownerLabel, const std::string &pathLabel, bool apply = true) { + check_exact_smack_accesses(ownerLabel, pathLabel, (apply ? owner_access : no_access)); +} + +void check_target_access(const std::string &ownerPkgLabel, const std::string &targetLabel, + const std::string &pathLabel, bool pathShared = true, bool anyPathShared = true) { + check_exact_smack_accesses(targetLabel, pathLabel, (pathShared ? target_path_access : no_access)); + check_exact_smack_accesses(targetLabel, ownerPkgLabel, (anyPathShared ? target_dir_access : no_access)); +} + +void check_path_label(const std::string &path, const std::string &expectedLabel) { + char *label = nullptr; + int ret = smack_new_label_from_path(path.c_str(), XATTR_NAME_SMACK, 0, &label); + RUNNER_ASSERT_MSG(ret > 0, "smack_new_label_from_path failed for " << path); + SmackLabelPtr realLabel(label); + RUNNER_ASSERT_MSG(realLabel.get() == expectedLabel, "Fetched label from " << path << " different" + " than expected, is : " << realLabel.get() << " should be " << expectedLabel); +} + +void createFile(const std::string &filePath) +{ + //create temporary file and set label for it + mode_t systemMask; + + unlink(filePath.c_str()); + //allow to create file with 777 rights + systemMask = umask(0000); + int fd = open(filePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); + //restore system mask + umask(systemMask); + RUNNER_ASSERT_ERRNO_MSG(fd > -1, "Unable to create file for tests"); + + //for descriptor protection + FdUniquePtr fd_ptr(&fd); + + //change owner and group to user APP + int ret = chown(filePath.c_str(), APP_UID, APP_GID); + RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Unable to change file owner"); +} + +} + +RUNNER_TEST(security_manager_30a_send_incomplete_req1) +{ + SharingRequest request; + Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE); + request.setOwnerAppId("someOwner"); + Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE); + request.setTargetAppId("someTarget"); + Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE); +} + +RUNNER_TEST(security_manager_30b_send_incomplete_req2) +{ + SharingRequest request; + request.setTargetAppId("someTarget"); + Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE); + request.setOwnerAppId("someOwner"); + Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE); +} + +RUNNER_TEST(security_manager_30c_send_incomplete_req3) +{ + SharingRequest request; + const char *somePaths[] = {"path1", "path2"}; + request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0])); + Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE); + request.setOwnerAppId("someOwner"); + Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE); +} + +RUNNER_TEST(security_manager_30d_unknown_owner) +{ + // This test depends on order of checks in security-manager service implementation + SharingRequest request; + request.setOwnerAppId("ImPrettySureIDontExist"); + request.setTargetAppId("IDontMatter"); + const char *somePaths[] = {"path1", "path2"}; + request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0])); + Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN); +} + +RUNNER_TEST(security_manager_30e_unknown_target) +{ + // This test depends on order of checks in security-manager service implementation + AppInstallHelper owner("installedApp"); + owner.revokeRules(); + owner.createInstallDir(); + InstallRequest ownerInst; + ownerInst.setAppId(owner.getAppId().c_str()); + ownerInst.setPkgId(owner.getPkgId().c_str()); + Api::install(ownerInst); + + SharingRequest request; + request.setOwnerAppId(owner.getAppId()); + request.setTargetAppId("NowImPrettySureIDontExist"); + const char *somePaths[] = {"path1", "path2"}; + request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0])); + Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN); + + Api::uninstall(ownerInst); +} + +RUNNER_TEST(security_manager_30f_bad_paths) +{ + // This test depends on order of checks in security-manager service implementation + AppInstallHelper owner("installedApp"); + owner.revokeRules(); + owner.createInstallDir(); + InstallRequest ownerInst; + ownerInst.setAppId(owner.getAppId().c_str()); + ownerInst.setPkgId(owner.getPkgId().c_str()); + Api::install(ownerInst); + + AppInstallHelper target("secondInstalledApp"); + target.revokeRules(); + target.createInstallDir(); + InstallRequest targetInst; + targetInst.setAppId(target.getAppId().c_str()); + targetInst.setPkgId(target.getPkgId().c_str()); + Api::install(targetInst); + + SharingRequest request; + request.setOwnerAppId(owner.getAppId()); + request.setTargetAppId(target.getAppId()); + + const char *somePath = "/tmp/somePath"; + createFile(somePath); + const char *somePaths[] = {somePath}; + request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0])); + Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER); + + Api::uninstall(ownerInst); +} + +RUNNER_TEST(security_manager_31_simple_share) +{ + std::vector helper {{"app30a"}, {"app30b"}}; + auto &owner = helper[0]; + auto &target = helper[1]; + + for (auto &e : helper) { + e.revokeRules(); + e.createInstallDir(); + } + + owner.createPrivateDir(); + owner.createSharedFile(); + + InstallRequest ownerReq; + ownerReq.setAppId(owner.getAppId().c_str()); + ownerReq.setPkgId(owner.getPkgId().c_str()); + ownerReq.addPath(owner.getSharedPath().c_str(), SECURITY_MANAGER_PATH_RW); + int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir()); + Api::install(ownerReq); + + InstallRequest targetReq; + targetReq.setAppId(target.getAppId().c_str()); + targetReq.setPkgId(target.getAppId().c_str()); + Api::install(targetReq); + + SharingRequest share1; + std::string sharedPath = owner.getSharedPath().c_str(); + share1.setOwnerAppId(owner.getAppId()); + share1.setTargetAppId(target.getAppId()); + const char *path[] = {sharedPath.c_str()}; + share1.addPaths(path, 1); + Api::applySharing(share1); + + TestSecurityManagerDatabase db; + std::string pathLabel1 = db.get_path_label(sharedPath.c_str()); + RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath); + + check_system_access(pathLabel1); + check_owner_access(owner.generateAppLabel(), pathLabel1); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1); + check_path_label(sharedPath, pathLabel1); + + Api::dropSharing(share1); + check_system_access(pathLabel1, false); + check_owner_access(owner.generateAppLabel(), pathLabel1, false); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false, false); + check_path_label(sharedPath, owner.generatePkgLabel()); + + Api::uninstall(ownerReq); + Api::uninstall(targetReq); +} + +RUNNER_TEST(security_manager_32_double_share) +{ + std::vector helper {{"app31a"}, {"app31b"}}; + auto &owner = helper[0]; + auto &target = helper[1]; + + // cleanup + for (auto &e : helper) { + e.revokeRules(); + e.createInstallDir(); + } + owner.createPrivateDir(); + owner.createSharedFile(); + + InstallRequest ownerReq; + ownerReq.setAppId(owner.getAppId().c_str()); + ownerReq.setPkgId(owner.getPkgId().c_str()); + ownerReq.addPath(owner.getSharedPath().c_str(), SECURITY_MANAGER_PATH_RW); + + int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir()); + Api::install(ownerReq); + + InstallRequest targetReq; + targetReq.setAppId(target.getAppId().c_str()); + targetReq.setPkgId(target.getAppId().c_str()); + Api::install(targetReq); + + SharingRequest share1; + std::string sharedPath = owner.getSharedPath(0).c_str(); + share1.setOwnerAppId(owner.getAppId()); + share1.setTargetAppId(target.getAppId()); + const char *path[] = {sharedPath.c_str()}; + share1.addPaths(path, 1); + Api::applySharing(share1); + + TestSecurityManagerDatabase db; + std::string pathLabel = db.get_path_label(sharedPath.c_str()); + RUNNER_ASSERT_MSG(!pathLabel.empty(), "Couldn't fetch path label from database for file " << sharedPath); + + check_system_access(pathLabel); + check_owner_access(owner.generateAppLabel(), pathLabel); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel); + check_path_label(sharedPath, pathLabel); + + Api::applySharing(share1); + check_system_access(pathLabel); + check_owner_access(owner.generateAppLabel(), pathLabel); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel); + check_path_label(sharedPath, pathLabel); + + Api::dropSharing(share1); + check_system_access(pathLabel); + check_owner_access(owner.generateAppLabel(), pathLabel); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel); + check_path_label(sharedPath, pathLabel); + + Api::dropSharing(share1); + check_system_access(pathLabel, false); + check_owner_access(owner.generateAppLabel(), pathLabel, false); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel, false, false); + check_path_label(sharedPath, owner.generatePkgLabel()); + + Api::uninstall(ownerReq); + Api::uninstall(targetReq); +} +RUNNER_TEST(security_manager_33_share_two_with_one) +{ + std::vector helper {{"app32a"}, {"app32b"}}; + auto &owner = helper[0]; + auto &target = helper[1]; + + // cleanup + for (auto &e : helper) { + e.revokeRules(); + e.createInstallDir(); + } + owner.createPrivateDir(); + owner.createSharedFile(0); + owner.createSharedFile(1); + + InstallRequest ownerReq; + ownerReq.setAppId(owner.getAppId().c_str()); + ownerReq.setPkgId(owner.getPkgId().c_str()); + ownerReq.addPath(owner.getSharedPath(0).c_str(), SECURITY_MANAGER_PATH_RW); + ownerReq.addPath(owner.getSharedPath(1).c_str(), SECURITY_MANAGER_PATH_RW); + + int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir()); + Api::install(ownerReq); + + InstallRequest targetReq; + targetReq.setAppId(target.getAppId().c_str()); + targetReq.setPkgId(target.getAppId().c_str()); + Api::install(targetReq); + + SharingRequest share1, share2; + std::string sharedPath1 = owner.getSharedPath(0).c_str(); + std::string sharedPath2 = owner.getSharedPath(1).c_str(); + share1.setOwnerAppId(owner.getAppId()); + share2.setOwnerAppId(owner.getAppId()); + share1.setTargetAppId(target.getAppId()); + share2.setTargetAppId(target.getAppId()); + const char *path1[] = {sharedPath1.c_str()}; + const char *path2[] = {sharedPath2.c_str()}; + share1.addPaths(path1, 1); + share2.addPaths(path2, 1); + + Api::applySharing(share1); + TestSecurityManagerDatabase db; + std::string pathLabel1 = db.get_path_label(sharedPath1.c_str()); + RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath1); + + check_system_access(pathLabel1); + check_owner_access(owner.generateAppLabel(), pathLabel1); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1); + check_path_label(sharedPath1, pathLabel1); + + Api::applySharing(share2); + std::string pathLabel2 = db.get_path_label(sharedPath2.c_str()); + RUNNER_ASSERT_MSG(!pathLabel2.empty(), "Couldn't fetch path label from database for file " << sharedPath2); + RUNNER_ASSERT_MSG(pathLabel1 != pathLabel2, "Labels for private shared paths should be unique!"); + + check_system_access(pathLabel1); + check_system_access(pathLabel2); + check_owner_access(owner.generateAppLabel(), pathLabel1); + check_owner_access(owner.generateAppLabel(), pathLabel2); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2); + check_path_label(sharedPath1, pathLabel1); + check_path_label(sharedPath2, pathLabel2); + + Api::dropSharing(share1); + check_system_access(pathLabel1, false); + check_system_access(pathLabel2); + check_owner_access(owner.generateAppLabel(), pathLabel1, false); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2); + check_path_label(sharedPath1, owner.generatePkgLabel()); + check_path_label(sharedPath2, pathLabel2); + + Api::dropSharing(share2); + check_system_access(pathLabel1, false); + check_system_access(pathLabel2, false); + check_owner_access(owner.generateAppLabel(), pathLabel1, false); + check_owner_access(owner.generateAppLabel(), pathLabel2, false); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false, false); + check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2, false, false); + check_path_label(sharedPath1, owner.generatePkgLabel()); + check_path_label(sharedPath2, owner.generatePkgLabel()); + + Api::uninstall(ownerReq); + Api::uninstall(targetReq); +} + +RUNNER_TEST(security_manager_34_share_one_with_two) +{ + std::vector helper {{"app33a"}, {"app33b"}, {"app33c"}}; + auto &owner = helper[0]; + auto &target1 = helper[1]; + auto &target2 = helper[2]; + + // cleanup + for (auto &e : helper) { + e.revokeRules(); + e.createInstallDir(); + } + owner.createPrivateDir(); + owner.createSharedFile(); + + InstallRequest ownerReq; + ownerReq.setAppId(owner.getAppId().c_str()); + ownerReq.setPkgId(owner.getPkgId().c_str()); + ownerReq.addPath(owner.getSharedPath().c_str(), SECURITY_MANAGER_PATH_RW); + int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir()); + Api::install(ownerReq); + + for (size_t i = 1; i < helper.size(); i++) { + InstallRequest targetReq; + targetReq.setAppId(helper[i].getAppId().c_str()); + targetReq.setPkgId(helper[i].getAppId().c_str()); + Api::install(targetReq); + } + + SharingRequest share1, share2; + std::string sharedPath = owner.getSharedPath(0).c_str(); + share1.setOwnerAppId(owner.getAppId()); + share2.setOwnerAppId(owner.getAppId()); + share1.setTargetAppId(target1.getAppId()); + share2.setTargetAppId(target2.getAppId()); + + const char *path[] = {sharedPath.c_str()}; + share1.addPaths(path, 1); + share2.addPaths(path, 1); + + Api::applySharing(share1); + TestSecurityManagerDatabase db; + std::string pathLabel = db.get_path_label(sharedPath.c_str()); + RUNNER_ASSERT_MSG(!pathLabel.empty(), "Couldn't fetch path label from database for file " << sharedPath); + + check_system_access(pathLabel); + check_owner_access(owner.generateAppLabel(), pathLabel); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel); + check_path_label(sharedPath, pathLabel); + + Api::applySharing(share2); + check_system_access(pathLabel); + check_owner_access(owner.generateAppLabel(), pathLabel); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel); + check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel); + check_path_label(sharedPath, pathLabel); + + Api::dropSharing(share1); + check_system_access(pathLabel); + check_owner_access(owner.generateAppLabel(), pathLabel); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel, false, false); + check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel); + check_path_label(sharedPath, pathLabel); + + Api::dropSharing(share2); + check_system_access(pathLabel, false); + check_owner_access(owner.generateAppLabel(), pathLabel, false); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel, false, false); + check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel, false, false); + check_path_label(sharedPath, owner.generatePkgLabel()); + + Api::uninstall(ownerReq); + for (size_t i = 1; i < helper.size(); i++) { + InstallRequest targetReq; + targetReq.setAppId(helper[i].getAppId().c_str()); + targetReq.setPkgId(helper[i].getAppId().c_str()); + Api::uninstall(targetReq); + } +} + +RUNNER_TEST(security_manager_35_share_two_with_two) +{ + std::vector helper {{"app34a"}, {"app34b"}, {"app34c"}}; + auto &owner = helper[0]; + auto &target1 = helper[1]; + auto &target2 = helper[2]; + + // cleanup + for (auto &e : helper) { + e.revokeRules(); + e.createInstallDir(); + } + owner.createPrivateDir(); + owner.createSharedFile(0); + owner.createSharedFile(1); + + InstallRequest ownerReq; + ownerReq.setAppId(owner.getAppId().c_str()); + ownerReq.setPkgId(owner.getPkgId().c_str()); + ownerReq.addPath(owner.getSharedPath(0).c_str(), SECURITY_MANAGER_PATH_RW); + ownerReq.addPath(owner.getSharedPath(1).c_str(), SECURITY_MANAGER_PATH_RW); + + int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir()); + Api::install(ownerReq); + + for (size_t i = 1; i < helper.size(); i++) { + InstallRequest targetReq; + targetReq.setAppId(helper[i].getAppId().c_str()); + targetReq.setPkgId(helper[i].getAppId().c_str()); + Api::install(targetReq); + } + + SharingRequest share1, share2; + std::string sharedPath1 = owner.getSharedPath(0).c_str(); + std::string sharedPath2 = owner.getSharedPath(1).c_str(); + share1.setOwnerAppId(owner.getAppId()); + share2.setOwnerAppId(owner.getAppId()); + share1.setTargetAppId(target1.getAppId()); + share2.setTargetAppId(target2.getAppId()); + + const char *path1[] = {sharedPath1.c_str()}; + const char *path2[] = {sharedPath2.c_str()}; + share1.addPaths(path1, 1); + share2.addPaths(path2, 1); + + Api::applySharing(share1); + TestSecurityManagerDatabase db; + std::string pathLabel1 = db.get_path_label(sharedPath1.c_str()); + RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath1); + + check_system_access(pathLabel1); + check_owner_access(owner.generateAppLabel(), pathLabel1); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1); + check_path_label(sharedPath1, pathLabel1); + + Api::applySharing(share2); + std::string pathLabel2 = db.get_path_label(sharedPath2.c_str()); + RUNNER_ASSERT_MSG(!pathLabel2.empty(), "Couldn't fetch path label from database for file " << sharedPath2); + RUNNER_ASSERT_MSG(pathLabel1 != pathLabel2, "Labels for shared files should be unique!"); + + check_system_access(pathLabel1); + check_system_access(pathLabel2); + check_owner_access(owner.generateAppLabel(), pathLabel1); + check_owner_access(owner.generateAppLabel(), pathLabel2); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1); + check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2); + check_path_label(sharedPath1, pathLabel1); + check_path_label(sharedPath2, pathLabel2); + + Api::dropSharing(share2); + check_system_access(pathLabel1); + check_system_access(pathLabel2, false); + check_owner_access(owner.generateAppLabel(), pathLabel1); + check_owner_access(owner.generateAppLabel(), pathLabel2, false); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1); + check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2, false, false); + check_path_label(sharedPath1, pathLabel1); + check_path_label(sharedPath2, owner.generatePkgLabel()); + + Api::dropSharing(share1); + check_system_access(pathLabel1, false); + check_system_access(pathLabel2, false); + check_owner_access(owner.generateAppLabel(), pathLabel1, false); + check_owner_access(owner.generateAppLabel(), pathLabel2, false); + check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1, false, false); + check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2, false, false); + check_path_label(sharedPath1, owner.generatePkgLabel()); + check_path_label(sharedPath2, owner.generatePkgLabel()); + Api::uninstall(ownerReq); + for (size_t i = 1; i < helper.size(); i++) { + InstallRequest targetReq; + targetReq.setAppId(helper[i].getAppId().c_str()); + targetReq.setPkgId(helper[i].getAppId().c_str()); + Api::uninstall(targetReq); + } +} + RUNNER_TEST(security_manager_40_set_wrong_author_id) { InstallRequest requestInst; -- 2.7.4