From 4972e31002982d465c667cbce1127f0d23a0dd14 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Wed, 17 Jan 2018 18:23:30 +0100 Subject: [PATCH] security-manager: fix tests related to privacy privileges When application is registered in security-manager with privileges that should be set as privacy, it is required to first register the app in security-privilege-manager. Otherwise, when security-manager checks if a privilege is privacy, it will always see privileges as non-privacy. This patch fixes the following tests: - security_manager_ap1_app_policy_fetch_for_self - security_manager_18_privacy_manager_privacy_related_privileges_policy_install_remove - security_manager_19a_privacy_manager_privacy_related_privileges_policy_hybrid - security_manager_19b_privacy_manager_privacy_related_privileges_policy_no_hybrid - security_manager_20_privacy_manager_privacy_related_privileges_policy_admin_check Change-Id: I34ec671f02a42e175ecbd53c428d17fcee65e909 Signed-off-by: Rafal Krypa --- src/common/CMakeLists.txt | 2 + src/common/app_def_privilege.h | 4 +- src/common/pkg_privacy_privileges.h | 81 ++++++++++++++++++++++ src/common/privilege_manager.cpp | 65 +++++++++++++++++ src/common/privilege_manager.h | 31 +++++++++ .../test_cases_app_policy.cpp | 17 +++-- .../test_cases_privacy_manager.cpp | 25 ++++--- 7 files changed, 209 insertions(+), 16 deletions(-) create mode 100644 src/common/pkg_privacy_privileges.h create mode 100644 src/common/privilege_manager.cpp create mode 100644 src/common/privilege_manager.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index caccd72..dc9aeeb 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -13,6 +13,7 @@ PKG_CHECK_MODULES(COMMON_TARGET_DEP cynara-creds-dbus cynara-creds-gdbus security-manager + security-privilege-manager REQUIRED ) @@ -44,6 +45,7 @@ SET(COMMON_TARGET_TEST_SOURCES ${PROJECT_SOURCE_DIR}/src/common/sm_user_request.cpp ${PROJECT_SOURCE_DIR}/src/common/sm_policy_request.cpp ${PROJECT_SOURCE_DIR}/src/common/tzplatform.cpp + ${PROJECT_SOURCE_DIR}/src/common/privilege_manager.cpp ) #system and local includes diff --git a/src/common/app_def_privilege.h b/src/common/app_def_privilege.h index 6d00972..d399dac 100644 --- a/src/common/app_def_privilege.h +++ b/src/common/app_def_privilege.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2018 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. @@ -29,6 +29,7 @@ public: UNSET, UNTRUSTED, LICENSED, + PRIVACY, }; Privilege(std::string systemPrivilege, Type type = UNSET, std::string license = std::string()) @@ -46,6 +47,7 @@ public: bool isUnset() const { return m_type == UNSET; } bool isUntrusted() const { return m_type == UNTRUSTED; } bool isLicensed() const { return m_type == LICENSED; } + bool isPrivacy() const { return m_type == PRIVACY; } int getType() const { return m_type; } app_defined_privilege_type getSMType () const { diff --git a/src/common/pkg_privacy_privileges.h b/src/common/pkg_privacy_privileges.h new file mode 100644 index 0000000..dfa6db5 --- /dev/null +++ b/src/common/pkg_privacy_privileges.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2018 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 +#include +#include +#include + +class PkgPrivacyPrivileges { +public: + PkgPrivacyPrivileges(const AppInstallHelper &app) + : m_pkgId(app.getPkgId()), + m_uid(app.getUID()), + m_creatorPid(getpid()), + m_shouldUnsetPrivacy(false) + { + std::vector privacyPrivileges; + for (const Privilege &privilege : app.getPrivileges()) + if (privilege.isPrivacy()) + privacyPrivileges.push_back(privilege.getName()); + + if (!privacyPrivileges.empty()) { + PrivilegeManager::setPrivacyPrivileges( + app.getUID(), app.getPkgId(), app.getVersion(), privacyPrivileges); + m_shouldUnsetPrivacy = true; + } + } + + PkgPrivacyPrivileges(const PkgPrivacyPrivileges &) = delete; + PkgPrivacyPrivileges(PkgPrivacyPrivileges &&other) + : m_pkgId(std::move(other.m_pkgId)), + m_uid(other.m_uid), + m_shouldUnsetPrivacy(other.m_shouldUnsetPrivacy) + { + other.m_uid = 0; + other.m_shouldUnsetPrivacy = false; + other.m_creatorPid = -1; + } + + PkgPrivacyPrivileges& operator=(const PkgPrivacyPrivileges &) = delete; + + virtual ~PkgPrivacyPrivileges() { + if (m_creatorPid == getpid()) + { + SafeCleanup::run([this]{ unsetPrivacy(); }); + } + } + + void unsetPrivacy() { + if (!m_shouldUnsetPrivacy) + return; + PrivilegeManager::unsetPrivacyPrivileges(m_uid, m_pkgId); + m_shouldUnsetPrivacy = false; + } + +protected: + std::string m_pkgId; + uid_t m_uid; + pid_t m_creatorPid; + bool m_shouldUnsetPrivacy; +}; diff --git a/src/common/privilege_manager.cpp b/src/common/privilege_manager.cpp new file mode 100644 index 0000000..01d1f47 --- /dev/null +++ b/src/common/privilege_manager.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018 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 +#include + +#include "dpl/test/test_runner.h" +#include "privilege_manager.h" + +namespace PrivilegeManager { + +void setPrivacyPrivileges(const uid_t uid, const std::string &pkgId, + const std::string &tizenVersion, const std::vector &privileges, + const privilege_manager_package_type_e &type) +{ + GList *list = nullptr; + + for (const std::string &privilege : privileges) { + gchar *str = g_strdup(privilege.c_str()); + if (str == nullptr) { + g_list_free_full(list, g_free); + throw std::bad_alloc(); + } + + GList *listNew = g_list_append(list, str); + if (listNew == nullptr) { + g_list_free_full(list, g_free); + throw std::bad_alloc(); + } + + list = listNew; + } + + int ret = privilege_package_info_set_privacy_privilege(uid, pkgId.c_str(), + type, tizenVersion.empty() ? "4.0" : tizenVersion.c_str(), list); + g_list_free_full(list, g_free); + + RUNNER_ASSERT_MSG(ret == PRVMGR_ERR_NONE, + "privilege_package_info_set_privacy_privilege failed: " << ret); +} + +void unsetPrivacyPrivileges(const uid_t uid, const std::string &pkgId) +{ + int ret = privilege_package_info_unset_package_privilege_info( + uid, pkgId.c_str()); + + RUNNER_ASSERT_MSG(ret == PRVMGR_ERR_NONE, + "privilege_package_info_unset_privacy_privilege failed: " << ret); +} + +} // namespace PrivilegeManager diff --git a/src/common/privilege_manager.h b/src/common/privilege_manager.h new file mode 100644 index 0000000..b46414a --- /dev/null +++ b/src/common/privilege_manager.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018 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 + +namespace PrivilegeManager { + +void setPrivacyPrivileges(const uid_t uid, const std::string &pkgId, + const std::string &tizenVersion, const std::vector &privileges, + const privilege_manager_package_type_e &type = PRVMGR_PACKAGE_TYPE_CORE); + +void unsetPrivacyPrivileges(const uid_t uid, const std::string &pkgId); + +} // namespace PrivilegeManager diff --git a/src/security-manager-tests/test_cases_app_policy.cpp b/src/security-manager-tests/test_cases_app_policy.cpp index afd9a09..bb3ab94 100644 --- a/src/security-manager-tests/test_cases_app_policy.cpp +++ b/src/security-manager-tests/test_cases_app_policy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2018 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. @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -27,10 +28,10 @@ #include #include -const std::vector TEST_PRIVACY_PRIVILEGES = { - "http://tizen.org/privilege/callhistory.read", - "http://tizen.org/privilege/account.read", - "http://tizen.org/privilege/healthinfo" }; +const PrivilegeVector TEST_PRIVACY_PRIVILEGES = { + Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY), + Privilege("http://tizen.org/privilege/account.read", Privilege::PRIVACY), + Privilege("http://tizen.org/privilege/healthinfo", Privilege::PRIVACY) }; using namespace SecurityManagerTest; @@ -49,6 +50,7 @@ RUNNER_CHILD_TEST(security_manager_ap1_app_policy_fetch_for_self) { RUNNER_ASSERT_MSG(isAskuserDisabled() || expectedPolicyCount > 0, "Application won't be installed with any privacy privileges, fix test"); + PkgPrivacyPrivileges setupPrivacyPrivs(app); ScopedInstaller appInstall(app); pid_t pid = fork(); @@ -103,6 +105,7 @@ RUNNER_CHILD_TEST(security_manager_ap2_app_policy_fetch_for_self_different_user) AppInstallHelper app("sm_test_ap2", tmpUser.getUid()); app.addPrivileges(TEST_PRIVACY_PRIVILEGES); + PkgPrivacyPrivileges setupPrivacyPrivs(app); ScopedInstaller appInstall(app); pid_t pid = fork(); @@ -137,6 +140,7 @@ RUNNER_CHILD_TEST(security_manager_ap3_app_policy_fetch_for_self_different_user_ app.setInstallType(SM_APP_INSTALL_GLOBAL); app.addPrivileges(TEST_PRIVACY_PRIVILEGES); + PkgPrivacyPrivileges setupPrivacyPrivs(app); ScopedInstaller appInstall(app); pid_t pid = fork(); @@ -171,7 +175,10 @@ RUNNER_CHILD_TEST(security_manager_ap3_app_policy_fetch_for_self_different_app) AppInstallHelper app2("sm_test_ap3_2", tmpUser.getUid()); app2.addPrivileges(TEST_PRIVACY_PRIVILEGES); + PkgPrivacyPrivileges setupPrivacyPrivs1(app1); ScopedInstaller appInstall1(app1); + + PkgPrivacyPrivileges setupPrivacyPrivs2(app2); ScopedInstaller appInstall2(app2); pid_t pid = fork(); diff --git a/src/security-manager-tests/test_cases_privacy_manager.cpp b/src/security-manager-tests/test_cases_privacy_manager.cpp index d40e864..eeec39a 100644 --- a/src/security-manager-tests/test_cases_privacy_manager.cpp +++ b/src/security-manager-tests/test_cases_privacy_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016-2018 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. @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -78,18 +79,18 @@ const std::vector TEST_PRIVILEGES = { } }; -const std::vector TEST_PRIVACY_PRIVILEGES = { +const PrivilegeVector TEST_PRIVACY_PRIVILEGES[] = { { - "http://tizen.org/privilege/telephony", - "http://tizen.org/privilege/led", - "http://tizen.org/privilege/callhistory.read", // privacy-related privileges start here - "http://tizen.org/privilege/account.read", - "http://tizen.org/privilege/healthinfo" + Privilege("http://tizen.org/privilege/telephony"), + Privilege("http://tizen.org/privilege/led"), + Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY), + Privilege("http://tizen.org/privilege/account.read", Privilege::PRIVACY), + Privilege("http://tizen.org/privilege/healthinfo", Privilege::PRIVACY), }, { - "http://tizen.org/privilege/telephony", - "http://tizen.org/privilege/led", - "http://tizen.org/privilege/callhistory.read" // privacy-related privileges start here + Privilege("http://tizen.org/privilege/telephony"), + Privilege("http://tizen.org/privilege/led"), + Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY), } }; @@ -836,6 +837,7 @@ RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges PolicyEntry filter (app.getAppId(), user.getUidString(), SECURITY_MANAGER_ANY); std::vector policyEntries; { + PkgPrivacyPrivileges setupPrivacyPrivs(app); ScopedInstaller installer(app); unsigned int privacyNum = countPrivacyPrivileges(app.getPrivileges()); @@ -878,12 +880,14 @@ void test_privacy_related_privileges(bool isHybrid) { if (isHybrid) app1.setHybrid(); app1.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]); + PkgPrivacyPrivileges setupPrivacyPrivs1(app1); ScopedInstaller installer1(app1); AppInstallHelper app2("sm_test_19_app_id_2", pkgId, user.getUid()); if (isHybrid) app2.setHybrid(); app2.addPrivileges(TEST_PRIVACY_PRIVILEGES[1]); + PkgPrivacyPrivileges setupPrivacyPrivs2(app2); ScopedInstaller installer2(app2); int privacyCount1, privacyCount2; @@ -941,6 +945,7 @@ RUNNER_CHILD_TEST(security_manager_20_privacy_manager_privacy_related_privileges AppInstallHelper app("sm_test_20", user.getUid()); app.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]); + PkgPrivacyPrivileges setupPrivacyPrivs(app); ScopedInstaller installer(app); CynaraTestAdmin::Admin admin; -- 2.7.4