From: Bartlomiej Grzelewski Date: Thu, 28 Jan 2016 18:57:12 +0000 (+0100) Subject: [SM] Tests for trusted dir. X-Git-Tag: security-manager_5.5_testing~109^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=184551e96cd90b5c1abeed4978a2c643b6050246;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git [SM] Tests for trusted dir. Change-Id: I4c97747253b8395a41bd85c004104f66bffc852a --- diff --git a/src/security-manager-tests/common/app_install_helper.h b/src/security-manager-tests/common/app_install_helper.h new file mode 100644 index 0000000..c79d263 --- /dev/null +++ b/src/security-manager-tests/common/app_install_helper.h @@ -0,0 +1,81 @@ +/* + * 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. + */ +#pragma once + +#include +#include +#include +#include + +#include + + +struct AppInstallHelper { + AppInstallHelper(const std::string &name) + : m_name(name) + {} + + std::string getInstallDir() { + return "/usr/apps/" + getPkgId(); + } + + std::string getTrustedDir(int i = 0) { + return getInstallDir() + "/trustedDir" + std::to_string(i); + } + + std::string getAppId() { + return m_name + "_app_id"; + } + + std::string getPkgId() { + return m_name + "_pkg_id"; + } + + void createInstallDir() { + mkdir(getInstallDir().c_str(), 0777); + } + + void createTrustedDir(int i = 0) { + mkdir(getTrustedDir(i).c_str(), 0777); + } + + void revokeRules() { + RUNNER_ASSERT_MSG( + 0 == smack_revoke_subject(generateAppLabel().c_str()), + "Revoking smack subject failed"); + RUNNER_ASSERT_MSG( + 0 == smack_revoke_subject(generatePkgLabel().c_str()), + "Revoking smack subject failed"); + } + + std::string generateAppLabel() { + return "User::App::" + getAppId(); + } + + std::string generatePkgLabel() { + return "User::Pkg::" + getPkgId(); + } + + virtual ~AppInstallHelper() { + // TODO we should also remove trusted dirs created with custom params + rmdir(getTrustedDir().c_str()); + rmdir(getInstallDir().c_str()); + } + +protected: + std::string m_name; +}; + diff --git a/src/security-manager-tests/common/sm_db.cpp b/src/security-manager-tests/common/sm_db.cpp index 10aa48c..7eb6f3f 100644 --- a/src/security-manager-tests/common/sm_db.cpp +++ b/src/security-manager-tests/common/sm_db.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -241,3 +241,25 @@ void TestSecurityManagerDatabase::setup_default_version_privilege(const std::str m_base.execute(sql.str(), result); } + +int64_t TestSecurityManagerDatabase::get_author_id(const std::string &authorName) +{ + Sqlite3DBaseSelectResult result; + std::ostringstream sql; + + if (!m_base.is_open()) + m_base.open(); + + sql.clear(); + sql.str("SELECT author_id FROM author where name=\"" + authorName + "\""); + m_base.execute(sql.str(), result); + + if(result.rows.empty()) + return 0; + + std::istringstream os(result.rows[0][0]); + int64_t id; + os >> id; + return id; +} + diff --git a/src/security-manager-tests/common/sm_db.h b/src/security-manager-tests/common/sm_db.h index 0cffde2..da71fbe 100644 --- a/src/security-manager-tests/common/sm_db.h +++ b/src/security-manager-tests/common/sm_db.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * 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. @@ -165,6 +165,11 @@ public: void setup_default_version_privilege(const std::string &version_from, const std::string &version_to, const std::string &privilege); + +/** + * @brief Method for getting author id from database. + */ + int64_t get_author_id(const std::string &authorName); private: /** * @var base diff --git a/src/security-manager-tests/common/sm_request.cpp b/src/security-manager-tests/common/sm_request.cpp index 65087af..69d1a4d 100644 --- a/src/security-manager-tests/common/sm_request.cpp +++ b/src/security-manager-tests/common/sm_request.cpp @@ -57,7 +57,7 @@ void InstallRequest::setAppId(const char *appId, lib_retcode expectedResult) << " App id: " << appId << ";" << " Result: " << result << ";" << " Expected result: " << expectedResult); - m_appId = appId; + m_appId = strdup(appId); } void InstallRequest::setPkgId(const char *pkgId, lib_retcode expectedResult) @@ -68,7 +68,7 @@ void InstallRequest::setPkgId(const char *pkgId, lib_retcode expectedResult) << " Pkg id: " << pkgId << ";" << " Result: " << result << ";" << " Expected result: " << expectedResult); - m_pkgId = pkgId; + m_pkgId = strdup(pkgId); } void InstallRequest::addPrivilege(const char *privilege, lib_retcode expectedResult) @@ -79,7 +79,7 @@ void InstallRequest::addPrivilege(const char *privilege, lib_retcode expectedRes << " Privilege: " << privilege << ";" << " Result: " << result << ";" << " Expected result: " << expectedResult); - m_privileges.push_back(privilege); + m_privileges.push_back(strdup(privilege)); } void InstallRequest::addPath(const char *path, app_install_path_type pathType, lib_retcode expectedResult) diff --git a/src/security-manager-tests/security_manager_tests.cpp b/src/security-manager-tests/security_manager_tests.cpp index efc6a85..417561c 100644 --- a/src/security-manager-tests/security_manager_tests.cpp +++ b/src/security-manager-tests/security_manager_tests.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +90,7 @@ std::string genOwnerRWOthersROPath(int app_num) { static const char *const SM_RW_PATH = "/usr/apps/sm_test_02_pkg_id_full/app_dir"; static const char *const SM_DENIED_PATH = "/usr/apps/non_app_dir"; +static const char *const SM_TRUSTED_PATH = "/usr/apps/sm_test_02_pkg_id_full/app_dir_trusted"; static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/ static const std::string EXEC_FILE("exec"); @@ -471,6 +474,31 @@ static inline struct passwd *getUserStruct(const uid_t uid) { return pw; }; +void check_exact_access(const std::string& subject, const std::string& object, const std::string& access) +{ + // check access + if (!access.empty()) { + int result = smack_have_access(subject.c_str(), object.c_str(), access.c_str()); + RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed"); + RUNNER_ASSERT_MSG(result == 1, + "No smack access: " << subject << " " << object << " " << access); + } + // check excessive access + auto foundInAccess = [&access](std::string::value_type c) { + return access.find(c) != std::string::npos; }; + + std::string negative = "rwxatl"; + auto end = std::remove_if(negative.begin(), negative.end(), foundInAccess); + negative.erase(end, negative.end()); + + for(const auto& c : negative) { + int result = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str()); + RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed"); + RUNNER_ASSERT_MSG(result == 0, + "Unexpected smack access: " << subject << " " << object << " " << c); + } +} + RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER) @@ -2731,14 +2759,14 @@ RUNNER_TEST(security_manager_27p_API30_app_uninstall) }; } -RUNNER_TEST(security_manager_27a_set_wrong_author_id) +RUNNER_TEST(security_manager_40_set_wrong_author_id) { InstallRequest requestInst; requestInst.setAuthorId(NULL, SECURITY_MANAGER_ERROR_INPUT_PARAM); requestInst.setAuthorId("", SECURITY_MANAGER_ERROR_INPUT_PARAM); } -RUNNER_TEST(security_manager_27b_set_author_id_multiple_times) +RUNNER_TEST(security_manager_41_set_author_id_multiple_times) { for(unsigned int i=0; i<10; ++i) { std::string authorId = "some-author-id" + std::to_string(i); @@ -2748,6 +2776,117 @@ RUNNER_TEST(security_manager_27b_set_author_id_multiple_times) } } +RUNNER_TEST(security_manager_43_app_install_with_trusted_path) +{ + std::vector helper {{"app43a"}, {"app43b"}, {"app43c"}}; + auto &provider = helper[0]; + auto &user = helper[1]; + auto &untrusted = helper[2]; + + TestSecurityManagerDatabase dbtest; + const char *author_id = "custom_author_id_test 41"; + + const char *const trusted_access = "rwxatl"; + const char *const system_access = "rwxatl"; + + int result; + + // cleanup + for (auto &e : helper) { + e.revokeRules(); + e.createInstallDir(); + e.createTrustedDir(); + } + + result = nftw(provider.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << SM_TRUSTED_PATH); + + // install app with shared/trusted dir + InstallRequest trustingApp; + trustingApp.setAppId(provider.getAppId().c_str()); + trustingApp.setPkgId(provider.getPkgId().c_str()); + trustingApp.setAuthorId("author id to be overwritten"); + trustingApp.setAuthorId(author_id); + trustingApp.addPath(provider.getTrustedDir().c_str(), SECURITY_MANAGER_PATH_TRUSTED_RW); + Api::install(trustingApp); + + int64_t authorDb = dbtest.get_author_id(author_id); + const std::string trusted_label = std::string("User::Author::") + std::to_string(authorDb); + + // check trusted path label + nftw_expected_label = trusted_label; + nftw_expected_transmute = true; + nftw_expected_exec = false; + + // check labels + result = nftw(provider.getTrustedDir().c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS); + RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_TRUSTED_PATH); + + // check rules + check_exact_access("System", trusted_label.c_str(), system_access); + check_exact_access("User", trusted_label.c_str(), system_access); + check_exact_access(generateAppLabel(provider.getAppId().c_str()), trusted_label, trusted_access); + check_exact_access(generatePkgLabel(provider.getPkgId().c_str()), trusted_label, ""); + + // install trusted app + InstallRequest trustedApp; + trustedApp.setAppId(user.getAppId().c_str()); + trustedApp.setPkgId(user.getPkgId().c_str()); + trustedApp.setAuthorId(author_id); + Api::install(trustedApp); + + // check rules + check_exact_access(generateAppLabel(user.getAppId().c_str()), trusted_label, trusted_access); + check_exact_access(generatePkgLabel(user.getPkgId().c_str()), trusted_label, ""); + + // install untrusted app + InstallRequest untrustedApp; + untrustedApp.setAppId(untrusted.getAppId().c_str()); + untrustedApp.setPkgId(untrusted.getPkgId().c_str()); + Api::install(untrustedApp); + + // check rules + check_exact_access(generateAppLabel(untrusted.getAppId().c_str()), trusted_label, ""); + check_exact_access(generatePkgLabel(untrusted.getPkgId().c_str()), trusted_label, ""); + + // uninstall trusting app + Api::uninstall(trustingApp); + + // there's still one app with author id, rules should be kept + check_exact_access("System", trusted_label, system_access); + check_exact_access("User", trusted_label, system_access); + check_exact_access(generateAppLabel(provider.getAppId().c_str()), trusted_label, ""); + check_exact_access(generatePkgLabel(provider.getPkgId().c_str()), trusted_label, ""); + check_exact_access(generateAppLabel(user.getAppId().c_str()), trusted_label, trusted_access); + check_exact_access(generatePkgLabel(user.getPkgId().c_str()), trusted_label, ""); + + Api::uninstall(trustedApp); + + // no more apps with author id + check_exact_access("System", trusted_label, ""); + check_exact_access("User", trusted_label, ""); + check_exact_access(generateAppLabel(user.getAppId().c_str()), trusted_label, ""); + check_exact_access(generatePkgLabel(user.getPkgId().c_str()), trusted_label, ""); + + Api::uninstall(untrustedApp); +} + + +RUNNER_TEST(security_manager_44_app_install_with_trusted_path_no_author_id) +{ + AppInstallHelper help("app44"); + help.createInstallDir(); + help.createTrustedDir(); + + // install app with shared/trusted dir but without authors id + InstallRequest app; + app.setAppId(help.getAppId().c_str()); + app.setPkgId(help.getPkgId().c_str()); + app.addPath(help.getTrustedDir().c_str(), + SECURITY_MANAGER_PATH_TRUSTED_RW); + Api::install(app, SECURITY_MANAGER_ERROR_INPUT_PARAM); +} + int main(int argc, char *argv[]) { return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);