2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <sys/smack.h>
18 #include <sys/capability.h>
19 #include <sys/prctl.h>
26 #include <dpl/test/test_runner_child.h>
27 #include <dpl/test/test_runner.h>
29 #include <app_install_helper.h>
30 #include <scoped_installer.h>
32 #include <sm_commons.h>
34 #include <tests_common.h>
36 using namespace SecurityManagerTest;
40 const size_t THREADS = 10;
42 const std::string APP_TEST_USER = "app_test_user";
44 typedef std::unique_ptr<_cap_struct, decltype(&cap_free)> CapPtr;
46 std::string thread_errors;
47 std::mutex error_mutex;
49 #define THREAD_ASSERT_MSG(test, message) \
54 std::ostringstream assertMsg; \
55 assertMsg << #test << " " << __FILE__ << " " << __LINE__ << " " << \
56 message << std::endl; \
57 std::lock_guard<std::mutex> guard(error_mutex); \
58 thread_errors.append(assertMsg.str()); \
62 void threadFn(int i, const std::string &expectedLabel)
67 THREAD_ASSERT_MSG(sigfillset(&sigset) == 0, "sigfillset failed");
68 THREAD_ASSERT_MSG(sigprocmask(SIG_BLOCK, &sigset, NULL) == 0, "sigprocmask failed");
75 THREAD_ASSERT_MSG(smack_new_label_from_self(&label) > 0, "smack_new_label_from_self failed");
76 CStringPtr labelPtr(label);
78 THREAD_ASSERT_MSG(expectedLabel.compare(label) == 0,
79 "Thread " << i << " has a wrong label: " << label);
81 CapPtr expectedCaps(cap_init(), cap_free);
82 THREAD_ASSERT_MSG(expectedCaps, "cap_init() failed");
83 THREAD_ASSERT_MSG(cap_clear(expectedCaps.get()) == 0, "cap_clear() failed");
85 CapPtr realCaps(cap_get_proc(), cap_free);
86 THREAD_ASSERT_MSG(realCaps, "cap_get_proc() failed");
87 THREAD_ASSERT_MSG(cap_compare(realCaps.get(), expectedCaps.get()) == 0,
88 "Thread " << i << " has wrong caps");
103 void run(int i, const std::string &expectedLabel)
105 THREAD_ASSERT_MSG(!thread.joinable(), "Thread already started");
106 thread = std::thread(threadFn, i, expectedLabel);
112 int setLauncherSecurityAttributes(TemporaryTestUser &user)
114 // Add launcher capabilities (cap_dac_override, cap_setgid, cap_sys_admin, cap_mac_admin),
115 // launcher is user process, we must drop root privileges (cap_setgid, cap_setuid are needed).
116 // By default, the permitted capability set is cleared when credentials change is made
117 // (if a process drops a capability from its permitted set, it can never reacquire that capability),
118 // setting the "keep capabilities" flag prevents it from being cleared.
119 // Effective capability set is always cleared when credential change is made, we need to add them again.
121 setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep cap_setuid+ep");
122 int ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0);
126 ret = drop_root_privileges(user.getUid(), user.getGid());
130 setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep");
134 } // anonymous namespace
136 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_PREPARE_APP)
138 RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_test)
140 TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
143 AppInstallHelper app("app100", tmpUser.getUid());
144 ScopedInstaller appInstall(app);
145 const std::string expectedLabel = app.generateAppLabel();
148 RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
151 RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
153 ThreadWrapper threads[THREADS];
155 for (size_t i = 0; i < THREADS; i++)
156 threads[i].run(i, expectedLabel);
158 Api::prepareApp(app.getAppId().c_str());
160 RUNNER_ASSERT_MSG(thread_errors.empty(), std::endl << thread_errors);