From: Radoslaw Bartosiak Date: Thu, 12 May 2016 21:09:41 +0000 (+0200) Subject: Test for API for managing list of permitted labels X-Git-Tag: security-manager_5.5_testing~20^2~67 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=802a549ab12887c3c3fa930f519dec086cb009e9;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git Test for API for managing list of permitted labels Four new API functions are tested: - security_manager_app_labels_monitor_init - security_manager_app_labels_monitor_finish - security_manager_app_labels_monitor_get_fd - security_manager_app_labels_monitor_process Change-Id: I238ac24820708c00078f0e79f27e3415061a22dd Signed-off-by: Radoslaw Bartosiak --- diff --git a/src/security-manager-tests/common/sm_api.cpp b/src/security-manager-tests/common/sm_api.cpp index c664482..620d76c 100644 --- a/src/security-manager-tests/common/sm_api.cpp +++ b/src/security-manager-tests/common/sm_api.cpp @@ -285,6 +285,38 @@ void registerPaths(const PathsRequest& req, lib_retcode expectedResult) << " Result: " << result << " Expected: " << expectedResult); } +void labelsMonitorInit(app_labels_monitor **monitor, lib_retcode expectedResult) +{ + int result = security_manager_app_labels_monitor_init(monitor); + RUNNER_ASSERT_MSG(static_cast(result) == expectedResult, + "Unexpected result in security_manager_app_labels_monitor_init()" + << std::endl << " Result: " << result << " Expected: " + << expectedResult); +}; + +void labelsMonitorFinish(app_labels_monitor *monitor) +{ + security_manager_app_labels_monitor_finish(monitor); +}; + +void labelsMonitorGetFd(app_labels_monitor *monitor, int *fd, lib_retcode expectedResult) +{ + int result = security_manager_app_labels_monitor_get_fd(monitor, fd); + RUNNER_ASSERT_MSG(static_cast(result) == expectedResult, + "Unexpected result in security_manager_app_labels_monitor_get_fd()" + << std::endl << " Result: " << result << " Expected: " + << expectedResult); +}; + +void labelsProcess(app_labels_monitor *monitor, lib_retcode expectedResult) +{ + int result = security_manager_app_labels_monitor_process(monitor); + RUNNER_ASSERT_MSG(static_cast(result) == expectedResult, + "Unexpected result in security_manager_app_labels_monitor_process()" + << std::endl << " Result: " << result << " Expected: " + << expectedResult); +} + } // namespace Api } // namespace SecurityManagerTest diff --git a/src/security-manager-tests/common/sm_api.h b/src/security-manager-tests/common/sm_api.h index 297add6..86cfd7d 100644 --- a/src/security-manager-tests/common/sm_api.h +++ b/src/security-manager-tests/common/sm_api.h @@ -23,6 +23,7 @@ #include #include +#include namespace SecurityManagerTest { @@ -48,8 +49,12 @@ void getPkgIdByPid(pid_t pid, std::string *pkgId, std::string *appId, lib_retcod void appHasPrivilege(const char *appId, const char *privilege, uid_t user, int &value, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void getSecurityManagerGroups(char ***groups, size_t *groups_count, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); void registerPaths(const PathsRequest& req, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); +void labelsMonitorInit(app_labels_monitor **monitor, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); +void labelsMonitorFinish(app_labels_monitor *monitor); +void labelsMonitorGetFd(app_labels_monitor *monitor, int *fd, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); +void labelsProcess(app_labels_monitor *monitor, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS); + } // namespace Api } // namespace SecurityManagerTest - #endif // SECURITY_MANAGER_TEST_API diff --git a/src/security-manager-tests/security_manager_tests.cpp b/src/security-manager-tests/security_manager_tests.cpp index ec210bd..b6888dc 100644 --- a/src/security-manager-tests/security_manager_tests.cpp +++ b/src/security-manager-tests/security_manager_tests.cpp @@ -7,14 +7,20 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include #include +#include #include #include +#include #include #include #include @@ -470,25 +476,33 @@ static void check_app_after_uninstall(const char *const app_id, const char *cons dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed); } -static void install_app(const char *app_id, const char *pkg_id, uid_t uid = 0) +static void install_app(const char *app_id, const char *pkg_id, uid_t uid = 0, + app_install_type type = SM_APP_INSTALL_NONE, bool check_after = true) { 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); - check_app_after_install(app_id, pkg_id); + if (check_after) + check_app_after_install(app_id, pkg_id); } -static void uninstall_app(const char *app_id, const char *pkg_id, bool expect_pkg_removed) +static void uninstall_app(const char *app_id, const char *pkg_id, + bool expect_pkg_removed = false, app_install_type type = SM_APP_INSTALL_NONE, + bool check_after = true) { InstallRequest request; request.setAppId(app_id); - + if (type != SM_APP_INSTALL_NONE) + request.setInstallType(type); Api::uninstall(request); - check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed); + if (check_after) + check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed); } static inline void register_current_process_as_privilege_manager(uid_t uid, bool forAdmin = false) @@ -5060,6 +5074,343 @@ RUNNER_TEST(security_manager_70_path_req_trusted_rw_positive) RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path); } +RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_LABEL_MONITOR_API) + +struct UidGidMsg { + uid_t uid; + gid_t gid; +}; + +static UidGidMsg createUserSendCreds(TemporaryTestUser &testUser, int pipefd1) +{ + testUser.create(); + UidGidMsg msg; + msg.uid = testUser.getUid(); + msg.gid = testUser.getGid(); + RUNNER_ASSERT_MSG(msg.uid != 0, "wrong uid of created test user"); + ssize_t written = TEMP_FAILURE_RETRY(write(pipefd1, &msg, sizeof(UidGidMsg))); + RUNNER_ASSERT_MSG((written == sizeof(UidGidMsg)),"write failed"); + return msg; +} + +static UidGidMsg readCreds(int pipefd0) +{ + struct UidGidMsg msg; + ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd0, &msg, sizeof(UidGidMsg))); + RUNNER_ASSERT_MSG(fetched == sizeof(UidGidMsg), "read failed"); + return msg; +} + +static void setCaps(const char *cap_string) +{ + CapsSetsUniquePtr caps(cap_init()); + caps.reset(cap_from_text(cap_string)); + RUNNER_ASSERT_MSG(caps, "can't convert capabilities from text"); + int result = cap_set_proc(caps.get()); + RUNNER_ASSERT_MSG(result == 0, "can't set capabilities. Result: " << result); +} + +static void testSetLabelForSelf(const char *app_id, bool expected_success) +{ + std::string label = generateAppLabel(app_id); + int result = smack_set_label_for_self(label.c_str()); + if (expected_success) + RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self(" << label << + ") failed. Error: " << result); + else + RUNNER_ASSERT_MSG(result != 0, "smack_set_label_for_self(" << label << + ") wrongly succeeded"); +} + +RUNNER_CHILD_TEST(security_manager_71_app_label_monitor_user_local_global) { + + const char *sm_app_id_a = "sm_test_71_app_label_monitor_local"; + const char *sm_pkg_id_a = "sm_test_71_app_label_monitor_local"; + const char *sm_app_id_b = "sm_test_71_app_label_monitor_global"; + const char *sm_pkg_id_b = "sm_test_71_app_label_monitor_global"; + const std::string new_user_name = "sm_test_71"; + int pipefd[2]; + RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed"); + SynchronizationPipe s_pipe; + + pid_t pid = fork(); + if (pid != 0) { //parent process + FdUniquePtr pipeptr(pipefd + 1); + close(pipefd[0]); + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + s_pipe.claimParentEp(); + s_pipe.wait(); //synchronization point A1 + install_app(sm_app_id_a, sm_pkg_id_a, msg.uid, SM_APP_INSTALL_LOCAL, false); + s_pipe.post(); //synchronization point A2 + s_pipe.wait(); //synchronization point B1 + install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_GLOBAL, false); + s_pipe.post(); //synchronization point B2 + s_pipe.wait(); //synchronization point C1 + uninstall_app(sm_app_id_a, sm_app_id_a, false, SM_APP_INSTALL_LOCAL, false); + s_pipe.post(); //synchronization point C2 + s_pipe.wait(); //synchronization point D1 + uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_GLOBAL, false); + s_pipe.post(); //synchronization point D2 + waitPid(pid); + } else { //child process + setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep"); + RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed"); + s_pipe.claimChildEp(); + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + UidGidMsg msg = readCreds(pipefd[0]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + setCaps("cap_mac_admin+ep"); + app_labels_monitor *monitor; + int fd; + nfds_t nfds = 1; + struct pollfd fds[1]; + Api::labelsMonitorInit(&monitor); + Api::labelsProcess(monitor); + Api::labelsMonitorGetFd(monitor, &fd); + fds[0].fd = fd; + fds[0].events = POLLIN; + for (int i = 0; i < 4; i++) { //A,B,C,D + s_pipe.post(); //synchronization point {A,B,C,D}1 + s_pipe.wait(); //synchronization point {A,B,C,D}2 + int poll_num = TEMP_FAILURE_RETRY(poll(fds, nfds, 0)); + RUNNER_ASSERT_MSG(poll_num > 0, "Application installation was not detected"); + RUNNER_ASSERT_MSG((fds[0].revents & POLLIN) > 0, "There is no data to read " + "regarding app installation"); + } + Api::labelsMonitorFinish(monitor); + } +} + +RUNNER_CHILD_TEST(security_manager_72_app_label_monitor_user_local) { + + const char *sm_app_id_a = "sm_test_72_app_label_monitor_local_1"; + const char *sm_pkg_id_a = "sm_test_72_app_label_monitor_local_1"; + const char *sm_app_id_b = "sm_test_72_app_label_monitor_local_2"; + const char *sm_pkg_id_b = "sm_test_72_app_label_monitor_local_2"; + const std::string new_user_name = "sm_test_75"; + + int pipefd[2]; + RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed"); + SynchronizationPipe s_pipe; + + pid_t pid = fork(); + if (pid != 0) { //parent process + FdUniquePtr pipeptr(pipefd + 1); + close(pipefd[0]); + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + s_pipe.claimParentEp(); + s_pipe.wait(); //synchronization point A1 + install_app(sm_app_id_a, sm_pkg_id_a, msg.uid, SM_APP_INSTALL_LOCAL, false); + s_pipe.post(); //synchronization point A2 + s_pipe.wait(); //synchronization point B1 + install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_LOCAL, false); + s_pipe.post(); //synchronization point B2 + s_pipe.wait(); //synchronization point C1 + uninstall_app(sm_app_id_a, sm_app_id_a, false, SM_APP_INSTALL_LOCAL, false); + s_pipe.post(); //synchronization point C2 + s_pipe.wait(); //synchronization point D1 + uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_LOCAL, false); + s_pipe.post(); //synchronization point D2 + waitPid(pid); + } else { //child process + setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep"); + RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed"); + s_pipe.claimChildEp(); + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + UidGidMsg msg = readCreds(pipefd[0]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + setCaps("cap_mac_admin+ep"); + app_labels_monitor *monitor; + int fd; + nfds_t nfds = 1; + struct pollfd fds[1]; + Api::labelsMonitorInit(&monitor); + Api::labelsProcess(monitor); + Api::labelsMonitorGetFd(monitor, &fd); + fds[0].fd = fd; + fds[0].events = POLLIN; + for (int i = 0; i < 4; i++) { //A,B,C,D + s_pipe.post(); //synchronization point {A,B,C,D}1 + s_pipe.wait(); //synchronization point {A,B,C,D}2 + int poll_num = TEMP_FAILURE_RETRY(poll(fds, nfds, 0)); + RUNNER_ASSERT_MSG(poll_num > 0, "Application installation was not detected"); + RUNNER_ASSERT_MSG((fds[0].revents & POLLIN) > 0, "There is no data to read " + "regarding app installation"); + } + Api::labelsMonitorFinish(monitor); + } +} + +RUNNER_CHILD_TEST(security_manager_73_app_label_monitor_different_users) { + + const char *sm_app_id_a = "sm_test_73_app_label_monitor_local_1"; + const char *sm_pkg_id_a = "sm_test_73_app_label_monitor_local_1"; + const char *sm_app_id_b = "sm_test_73_app_label_monitor_global_2"; + const char *sm_pkg_id_b = "sm_test_73_app_label_monitor_global_2"; + const std::string new_user_name_1 = "sm_test_73_1"; + const std::string new_user_name_2 = "sm_test_73_2"; + + SynchronizationPipe s_pipe; + + pid_t pid = fork(); + if (pid != 0) { //parent process + s_pipe.claimParentEp(); + TemporaryTestUser testUserOne(new_user_name_1, GUM_USERTYPE_NORMAL, false); + testUserOne.create(); + s_pipe.post(); //synchronization point A for user creation + int result = drop_root_privileges(testUserOne.getUid(), testUserOne.getGid()); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + install_app(sm_app_id_a, sm_pkg_id_a, testUserOne.getUid(), SM_APP_INSTALL_LOCAL, false); + install_app(sm_app_id_b, sm_pkg_id_b, testUserOne.getUid(), SM_APP_INSTALL_GLOBAL, false); + s_pipe.post(); //synchronization point B + s_pipe.wait(); //synchronization point C + uninstall_app(sm_app_id_a, sm_app_id_a, false, SM_APP_INSTALL_LOCAL, false); + uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_LOCAL, false); + waitPid(pid); + } else { //child process + setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep"); + RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed"); + s_pipe.claimChildEp(); + s_pipe.wait(); //synchronization point A for user creation + TemporaryTestUser testUserTwo(new_user_name_2, GUM_USERTYPE_NORMAL, false); + testUserTwo.create(); + int result = drop_root_privileges(testUserTwo.getUid(), testUserTwo.getGid()); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + setCaps("cap_mac_admin+ep"); + app_labels_monitor *monitor; + Api::labelsMonitorInit(&monitor); + s_pipe.wait(); //B + Api::labelsProcess(monitor); + Api::labelsMonitorFinish(monitor); + setCaps("cap_mac_admin-eip"); + testSetLabelForSelf(sm_app_id_a, false); // local installation by another user + testSetLabelForSelf(sm_app_id_b, true); // global installation by another user + s_pipe.post(); //C + } +} + +RUNNER_CHILD_TEST(security_manager_74_app_label_monitor_relabel_changes_1) { + + const char *sm_app_id_a = "sm_test_74_app_label_monitor_global_1"; + const char *sm_pkg_id_a = "sm_test_74_app_label_monitor_global_1"; + const char *sm_app_id_b = "sm_test_74_app_label_monitor_global_2"; + const char *sm_pkg_id_b = "sm_test_74_app_label_monitor_global_2"; + const char *sm_app_id_c = "sm_test_74_app_label_monitor_global_3"; + const char *sm_pkg_id_c = "sm_test_74_app_label_monitor_global_3"; + const std::string new_user_name = "sm_test_74"; + + int pipefd[2]; + RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed"); + SynchronizationPipe s_pipe; + + pid_t pid = fork(); + if (pid != 0) { //parent process + FdUniquePtr pipeptr(pipefd + 1); + close(pipefd[0]); + s_pipe.claimParentEp(); + install_app(sm_app_id_a, sm_pkg_id_a, getuid(), SM_APP_INSTALL_GLOBAL); + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_GLOBAL, false); + install_app(sm_app_id_c, sm_pkg_id_c, msg.gid, SM_APP_INSTALL_GLOBAL, false); + s_pipe.post(); //Synchronization point A + s_pipe.wait(); //Synchronization point B + uninstall_app(sm_app_id_a, sm_pkg_id_a, false, SM_APP_INSTALL_GLOBAL, false); + uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_GLOBAL, false); + uninstall_app(sm_app_id_c, sm_app_id_c, false, SM_APP_INSTALL_GLOBAL, false); + waitPid(pid); + } else { //child process + setCaps("all=eip"); + RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed"); + s_pipe.claimChildEp(); + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + UidGidMsg msg = readCreds(pipefd[0]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + setCaps("cap_mac_admin=eip"); + app_labels_monitor *monitor; + Api::labelsMonitorInit(&monitor); + s_pipe.wait(); //A + Api::labelsProcess(monitor); + Api::labelsMonitorFinish(monitor); + setCaps("cap_mac_admin-eip"); + testSetLabelForSelf(sm_app_id_a, true); // global installation (OK) + testSetLabelForSelf(sm_app_id_b, false); //second change + testSetLabelForSelf(sm_app_id_c, false); //second change + s_pipe.post(); //B + } +} + +RUNNER_CHILD_TEST(security_manager_75_app_label_monitor_relabel_changes_2) { + + const char *sm_app_id_a = "sm_test_75_app_label_monitor_local_1"; + const char *sm_pkg_id_a = "sm_test_75_app_label_monitor_local_1"; + const char *sm_app_id_b = "sm_test_75_app_label_monitor_local_2"; + const char *sm_pkg_id_b = "sm_test_75_app_label_monitor_local_2"; + const char *sm_app_id_c = "sm_test_75_app_label_monitor_local_3"; + const char *sm_pkg_id_c = "sm_test_75_app_label_monitor_local_3"; + const char *bad_seed ="Not_permitted_id"; + const std::string new_user_name = "sm_test_75"; + + int pipefd[2]; + RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed"); + SynchronizationPipe s_pipe; + + pid_t pid = fork(); + if (pid != 0) { //parent process + FdUniquePtr pipeptr(pipefd + 1); + close(pipefd[0]); + s_pipe.claimParentEp(); + TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false); + UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + install_app(sm_app_id_a, sm_pkg_id_a, msg.uid, SM_APP_INSTALL_LOCAL, false); + install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_LOCAL, false); + install_app(sm_app_id_c, sm_pkg_id_c, msg.uid, SM_APP_INSTALL_LOCAL, false); + uninstall_app(sm_app_id_a, sm_pkg_id_a, false, SM_APP_INSTALL_LOCAL, false); + s_pipe.post(); //Synchronization A + s_pipe.wait(); //Synchronization B + uninstall_app(sm_app_id_b, sm_pkg_id_b, false, SM_APP_INSTALL_LOCAL, false); + uninstall_app(sm_app_id_c, sm_pkg_id_c, false, SM_APP_INSTALL_LOCAL, false); + waitPid(pid); + } else { //child process + setCaps("all=eip"); + RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed"); + s_pipe.claimChildEp(); + FdUniquePtr pipeptr(pipefd); + close(pipefd[1]); + UidGidMsg msg = readCreds(pipefd[0]); + int result = drop_root_privileges(msg.uid, msg.gid); + RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed"); + setCaps("cap_mac_admin=eip"); + app_labels_monitor *monitor; + Api::labelsMonitorInit(&monitor); + s_pipe.wait(); //A + Api::labelsProcess(monitor); + Api::labelsMonitorFinish(monitor); + setCaps("cap_mac_admin-eip"); + testSetLabelForSelf(bad_seed, false); //not premitted + testSetLabelForSelf(sm_app_id_a, false); //uninstalled + testSetLabelForSelf(sm_app_id_b, true); //installed + testSetLabelForSelf(sm_app_id_c, false); //second change + s_pipe.post(); //B + } +} + int main(int argc, char *argv[]) { return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);