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.
18 #include <sys/smack.h>
19 #include <sys/types.h>
22 #include <app_install_helper.h>
23 #include <dpl/test/test_runner.h>
26 #include <sys/prctl.h>
28 #include <sm_commons.h>
29 #include <synchronization_pipe.h>
30 #include <temp_test_user.h>
31 #include <tests_common.h>
33 using namespace SecurityManagerTest;
40 static UidGidMsg createUserSendCreds(TemporaryTestUser &testUser, int pipefd1)
44 msg.uid = testUser.getUid();
45 msg.gid = testUser.getGid();
46 RUNNER_ASSERT_MSG(msg.uid != 0, "wrong uid of created test user");
47 ssize_t written = TEMP_FAILURE_RETRY(write(pipefd1, &msg, sizeof(UidGidMsg)));
48 RUNNER_ASSERT_MSG((written == sizeof(UidGidMsg)),"write failed");
52 static UidGidMsg readCreds(int pipefd0)
55 ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd0, &msg, sizeof(UidGidMsg)));
56 RUNNER_ASSERT_MSG(fetched == sizeof(UidGidMsg), "read failed");
60 static void testSetLabelForSelf(const char *app_id, bool expected_success)
62 std::string label = generateAppLabel(app_id);
63 int result = smack_set_label_for_self(label.c_str());
65 RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self(" << label <<
66 ") failed. Error: " << result);
68 RUNNER_ASSERT_MSG(result != 0, "smack_set_label_for_self(" << label <<
69 ") wrongly succeeded");
72 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_LABEL_MONITOR_API)
74 RUNNER_CHILD_TEST(security_manager_71_app_label_monitor_user_local_global) {
76 const char *sm_app_id_a = "sm_test_71_app_label_monitor_local";
77 const char *sm_pkg_id_a = "sm_test_71_app_label_monitor_local";
78 const char *sm_app_id_b = "sm_test_71_app_label_monitor_global";
79 const char *sm_pkg_id_b = "sm_test_71_app_label_monitor_global";
80 const std::string new_user_name = "sm_test_71";
82 RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
83 SynchronizationPipe s_pipe;
86 if (pid != 0) { //parent process
87 FdUniquePtr pipeptr(pipefd + 1);
89 TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false);
90 UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]);
91 int result = drop_root_privileges(msg.uid, msg.gid);
92 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
93 s_pipe.claimParentEp();
94 s_pipe.wait(); //synchronization point A1
95 install_app(sm_app_id_a, sm_pkg_id_a, msg.uid, SM_APP_INSTALL_LOCAL, false);
96 s_pipe.post(); //synchronization point A2
97 s_pipe.wait(); //synchronization point B1
98 install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_GLOBAL, false);
99 s_pipe.post(); //synchronization point B2
100 s_pipe.wait(); //synchronization point C1
101 uninstall_app(sm_app_id_a, sm_app_id_a, false, SM_APP_INSTALL_LOCAL, false);
102 s_pipe.post(); //synchronization point C2
103 s_pipe.wait(); //synchronization point D1
104 uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_GLOBAL, false);
105 s_pipe.post(); //synchronization point D2
107 } else { //child process
108 setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep");
109 RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
110 s_pipe.claimChildEp();
111 FdUniquePtr pipeptr(pipefd);
113 UidGidMsg msg = readCreds(pipefd[0]);
114 int result = drop_root_privileges(msg.uid, msg.gid);
115 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
116 setCaps("cap_mac_admin+ep");
117 app_labels_monitor *monitor;
120 struct pollfd fds[1];
121 Api::labelsMonitorInit(&monitor);
122 Api::labelsProcess(monitor);
123 Api::labelsMonitorGetFd(monitor, &fd);
125 fds[0].events = POLLIN;
126 for (int i = 0; i < 4; i++) { //A,B,C,D
127 s_pipe.post(); //synchronization point {A,B,C,D}1
128 s_pipe.wait(); //synchronization point {A,B,C,D}2
129 int poll_num = TEMP_FAILURE_RETRY(poll(fds, nfds, 0));
130 RUNNER_ASSERT_MSG(poll_num > 0, "Application installation was not detected");
131 RUNNER_ASSERT_MSG((fds[0].revents & POLLIN) > 0, "There is no data to read "
132 "regarding app installation");
134 Api::labelsMonitorFinish(monitor);
138 RUNNER_CHILD_TEST(security_manager_72_app_label_monitor_user_local) {
140 const char *sm_app_id_a = "sm_test_72_app_label_monitor_local_1";
141 const char *sm_pkg_id_a = "sm_test_72_app_label_monitor_local_1";
142 const char *sm_app_id_b = "sm_test_72_app_label_monitor_local_2";
143 const char *sm_pkg_id_b = "sm_test_72_app_label_monitor_local_2";
144 const std::string new_user_name = "sm_test_75";
147 RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
148 SynchronizationPipe s_pipe;
151 if (pid != 0) { //parent process
152 FdUniquePtr pipeptr(pipefd + 1);
154 TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false);
155 UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]);
156 int result = drop_root_privileges(msg.uid, msg.gid);
157 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
158 s_pipe.claimParentEp();
159 s_pipe.wait(); //synchronization point A1
160 install_app(sm_app_id_a, sm_pkg_id_a, msg.uid, SM_APP_INSTALL_LOCAL, false);
161 s_pipe.post(); //synchronization point A2
162 s_pipe.wait(); //synchronization point B1
163 install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_LOCAL, false);
164 s_pipe.post(); //synchronization point B2
165 s_pipe.wait(); //synchronization point C1
166 uninstall_app(sm_app_id_a, sm_app_id_a, false, SM_APP_INSTALL_LOCAL, false);
167 s_pipe.post(); //synchronization point C2
168 s_pipe.wait(); //synchronization point D1
169 uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_LOCAL, false);
170 s_pipe.post(); //synchronization point D2
172 } else { //child process
173 setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep");
174 RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
175 s_pipe.claimChildEp();
176 FdUniquePtr pipeptr(pipefd);
178 UidGidMsg msg = readCreds(pipefd[0]);
179 int result = drop_root_privileges(msg.uid, msg.gid);
180 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
181 setCaps("cap_mac_admin+ep");
182 app_labels_monitor *monitor;
185 struct pollfd fds[1];
186 Api::labelsMonitorInit(&monitor);
187 Api::labelsProcess(monitor);
188 Api::labelsMonitorGetFd(monitor, &fd);
190 fds[0].events = POLLIN;
191 for (int i = 0; i < 4; i++) { //A,B,C,D
192 s_pipe.post(); //synchronization point {A,B,C,D}1
193 s_pipe.wait(); //synchronization point {A,B,C,D}2
194 int poll_num = TEMP_FAILURE_RETRY(poll(fds, nfds, 0));
195 RUNNER_ASSERT_MSG(poll_num > 0, "Application installation was not detected");
196 RUNNER_ASSERT_MSG((fds[0].revents & POLLIN) > 0, "There is no data to read "
197 "regarding app installation");
199 Api::labelsMonitorFinish(monitor);
203 RUNNER_CHILD_TEST(security_manager_73_app_label_monitor_different_users) {
205 const char *sm_app_id_a = "sm_test_73_app_label_monitor_local_1";
206 const char *sm_pkg_id_a = "sm_test_73_app_label_monitor_local_1";
207 const char *sm_app_id_b = "sm_test_73_app_label_monitor_global_2";
208 const char *sm_pkg_id_b = "sm_test_73_app_label_monitor_global_2";
209 const std::string new_user_name_1 = "sm_test_73_1";
210 const std::string new_user_name_2 = "sm_test_73_2";
212 SynchronizationPipe s_pipe;
215 if (pid != 0) { //parent process
216 s_pipe.claimParentEp();
217 TemporaryTestUser testUserOne(new_user_name_1, GUM_USERTYPE_NORMAL, false);
218 testUserOne.create();
219 s_pipe.post(); //synchronization point A for user creation
220 int result = drop_root_privileges(testUserOne.getUid(), testUserOne.getGid());
221 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
222 install_app(sm_app_id_a, sm_pkg_id_a, testUserOne.getUid(), SM_APP_INSTALL_LOCAL, false);
223 install_app(sm_app_id_b, sm_pkg_id_b, testUserOne.getUid(), SM_APP_INSTALL_GLOBAL, false);
224 s_pipe.post(); //synchronization point B
225 s_pipe.wait(); //synchronization point C
226 uninstall_app(sm_app_id_a, sm_app_id_a, false, SM_APP_INSTALL_LOCAL, false);
227 uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_LOCAL, false);
229 } else { //child process
230 setCaps("cap_mac_admin+ep cap_setuid+ep cap_setgid+ep");
231 RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
232 s_pipe.claimChildEp();
233 s_pipe.wait(); //synchronization point A for user creation
234 TemporaryTestUser testUserTwo(new_user_name_2, GUM_USERTYPE_NORMAL, false);
235 testUserTwo.create();
236 int result = drop_root_privileges(testUserTwo.getUid(), testUserTwo.getGid());
237 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
238 setCaps("cap_mac_admin+ep");
239 app_labels_monitor *monitor;
240 Api::labelsMonitorInit(&monitor);
242 Api::labelsProcess(monitor);
243 Api::labelsMonitorFinish(monitor);
244 setCaps("cap_mac_admin-eip");
245 testSetLabelForSelf(sm_app_id_a, false); // local installation by another user
246 testSetLabelForSelf(sm_app_id_b, true); // global installation by another user
251 RUNNER_CHILD_TEST(security_manager_74_app_label_monitor_relabel_changes_1) {
253 const char *sm_app_id_a = "sm_test_74_app_label_monitor_global_1";
254 const char *sm_pkg_id_a = "sm_test_74_app_label_monitor_global_1";
255 const char *sm_app_id_b = "sm_test_74_app_label_monitor_global_2";
256 const char *sm_pkg_id_b = "sm_test_74_app_label_monitor_global_2";
257 const char *sm_app_id_c = "sm_test_74_app_label_monitor_global_3";
258 const char *sm_pkg_id_c = "sm_test_74_app_label_monitor_global_3";
259 const std::string new_user_name = "sm_test_74";
262 RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
263 SynchronizationPipe s_pipe;
266 if (pid != 0) { //parent process
267 FdUniquePtr pipeptr(pipefd + 1);
269 s_pipe.claimParentEp();
270 install_app(sm_app_id_a, sm_pkg_id_a, getuid(), SM_APP_INSTALL_GLOBAL);
271 TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false);
272 UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]);
273 int result = drop_root_privileges(msg.uid, msg.gid);
274 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
275 install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_GLOBAL, false);
276 install_app(sm_app_id_c, sm_pkg_id_c, msg.gid, SM_APP_INSTALL_GLOBAL, false);
277 s_pipe.post(); //Synchronization point A
278 s_pipe.wait(); //Synchronization point B
279 uninstall_app(sm_app_id_a, sm_pkg_id_a, false, SM_APP_INSTALL_GLOBAL, false);
280 uninstall_app(sm_app_id_b, sm_app_id_b, false, SM_APP_INSTALL_GLOBAL, false);
281 uninstall_app(sm_app_id_c, sm_app_id_c, false, SM_APP_INSTALL_GLOBAL, false);
283 } else { //child process
285 RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
286 s_pipe.claimChildEp();
287 FdUniquePtr pipeptr(pipefd);
289 UidGidMsg msg = readCreds(pipefd[0]);
290 int result = drop_root_privileges(msg.uid, msg.gid);
291 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
292 setCaps("cap_mac_admin=eip");
293 app_labels_monitor *monitor;
294 Api::labelsMonitorInit(&monitor);
296 Api::labelsProcess(monitor);
297 Api::labelsMonitorFinish(monitor);
298 setCaps("cap_mac_admin-eip");
299 testSetLabelForSelf(sm_app_id_a, true); // global installation (OK)
300 testSetLabelForSelf(sm_app_id_b, false); //second change
301 testSetLabelForSelf(sm_app_id_c, false); //second change
306 RUNNER_CHILD_TEST(security_manager_75_app_label_monitor_relabel_changes_2) {
308 const char *sm_app_id_a = "sm_test_75_app_label_monitor_local_1";
309 const char *sm_pkg_id_a = "sm_test_75_app_label_monitor_local_1";
310 const char *sm_app_id_b = "sm_test_75_app_label_monitor_local_2";
311 const char *sm_pkg_id_b = "sm_test_75_app_label_monitor_local_2";
312 const char *sm_app_id_c = "sm_test_75_app_label_monitor_local_3";
313 const char *sm_pkg_id_c = "sm_test_75_app_label_monitor_local_3";
314 const char *bad_seed ="Not_permitted_id";
315 const std::string new_user_name = "sm_test_75";
318 RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
319 SynchronizationPipe s_pipe;
322 if (pid != 0) { //parent process
323 FdUniquePtr pipeptr(pipefd + 1);
325 s_pipe.claimParentEp();
326 TemporaryTestUser testUser(new_user_name, GUM_USERTYPE_NORMAL, false);
327 UidGidMsg msg = createUserSendCreds(testUser, pipefd[1]);
328 int result = drop_root_privileges(msg.uid, msg.gid);
329 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
330 install_app(sm_app_id_a, sm_pkg_id_a, msg.uid, SM_APP_INSTALL_LOCAL, false);
331 install_app(sm_app_id_b, sm_pkg_id_b, msg.uid, SM_APP_INSTALL_LOCAL, false);
332 install_app(sm_app_id_c, sm_pkg_id_c, msg.uid, SM_APP_INSTALL_LOCAL, false);
333 uninstall_app(sm_app_id_a, sm_pkg_id_a, false, SM_APP_INSTALL_LOCAL, false);
334 s_pipe.post(); //Synchronization A
335 s_pipe.wait(); //Synchronization B
336 uninstall_app(sm_app_id_b, sm_pkg_id_b, false, SM_APP_INSTALL_LOCAL, false);
337 uninstall_app(sm_app_id_c, sm_pkg_id_c, false, SM_APP_INSTALL_LOCAL, false);
339 } else { //child process
341 RUNNER_ASSERT_ERRNO_MSG(prctl(PR_SET_KEEPCAPS, 1, 0, 0) == 0, "prctl keeping caps failed");
342 s_pipe.claimChildEp();
343 FdUniquePtr pipeptr(pipefd);
345 UidGidMsg msg = readCreds(pipefd[0]);
346 int result = drop_root_privileges(msg.uid, msg.gid);
347 RUNNER_ASSERT_MSG(result == 0, "drop_root_privileges failed");
348 setCaps("cap_mac_admin=eip");
349 app_labels_monitor *monitor;
350 Api::labelsMonitorInit(&monitor);
352 Api::labelsProcess(monitor);
353 Api::labelsMonitorFinish(monitor);
354 setCaps("cap_mac_admin-eip");
355 testSetLabelForSelf(bad_seed, false); //not premitted
356 testSetLabelForSelf(sm_app_id_a, false); //uninstalled
357 testSetLabelForSelf(sm_app_id_b, true); //installed
358 testSetLabelForSelf(sm_app_id_c, false); //second change