SM: Code cleanup - separate dyntransition tests
[platform/core/test/security-tests.git] / src / security-manager-tests / test_cases_dyntransition.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <string>
18 #include <sys/smack.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21
22 #include <app_install_helper.h>
23 #include <dpl/test/test_runner.h>
24 #include <memory.h>
25 #include <poll.h>
26 #include <sys/prctl.h>
27 #include <sm_api.h>
28 #include <sm_commons.h>
29 #include <synchronization_pipe.h>
30 #include <temp_test_user.h>
31 #include <tests_common.h>
32
33 using namespace SecurityManagerTest;
34
35 struct UidGidMsg {
36     uid_t uid;
37     gid_t gid;
38 };
39
40 static UidGidMsg createUserSendCreds(TemporaryTestUser &testUser, int pipefd1)
41 {
42     testUser.create();
43     UidGidMsg msg;
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");
49     return msg;
50 }
51
52 static UidGidMsg readCreds(int pipefd0)
53 {
54     struct UidGidMsg msg;
55     ssize_t fetched = TEMP_FAILURE_RETRY(read(pipefd0, &msg, sizeof(UidGidMsg)));
56     RUNNER_ASSERT_MSG(fetched == sizeof(UidGidMsg), "read failed");
57     return msg;
58 }
59
60 static void testSetLabelForSelf(const char *app_id, bool expected_success)
61 {
62     std::string label =  generateAppLabel(app_id);
63     int result = smack_set_label_for_self(label.c_str());
64     if (expected_success)
65         RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self(" << label <<
66                 ") failed. Error: " << result);
67     else
68         RUNNER_ASSERT_MSG(result != 0, "smack_set_label_for_self(" << label <<
69                 ") wrongly succeeded");
70 }
71
72 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_LABEL_MONITOR_API)
73
74 RUNNER_CHILD_TEST(security_manager_71_app_label_monitor_user_local_global) {
75
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";
81     int pipefd[2];
82     RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
83     SynchronizationPipe s_pipe;
84
85     pid_t pid = fork();
86     if (pid != 0) { //parent process
87         FdUniquePtr pipeptr(pipefd + 1);
88         close(pipefd[0]);
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
106         waitPid(pid);
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);
112         close(pipefd[1]);
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;
118         int fd;
119         nfds_t nfds = 1;
120         struct pollfd fds[1];
121         Api::labelsMonitorInit(&monitor);
122         Api::labelsProcess(monitor);
123         Api::labelsMonitorGetFd(monitor, &fd);
124         fds[0].fd = 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");
133         }
134         Api::labelsMonitorFinish(monitor);
135     }
136 }
137
138 RUNNER_CHILD_TEST(security_manager_72_app_label_monitor_user_local) {
139
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";
145
146     int pipefd[2];
147     RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
148     SynchronizationPipe s_pipe;
149
150     pid_t pid = fork();
151         if (pid != 0) { //parent process
152             FdUniquePtr pipeptr(pipefd + 1);
153             close(pipefd[0]);
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
171             waitPid(pid);
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);
177             close(pipefd[1]);
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;
183             int fd;
184             nfds_t nfds = 1;
185             struct pollfd fds[1];
186             Api::labelsMonitorInit(&monitor);
187             Api::labelsProcess(monitor);
188             Api::labelsMonitorGetFd(monitor, &fd);
189             fds[0].fd = 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");
198             }
199             Api::labelsMonitorFinish(monitor);
200         }
201 }
202
203 RUNNER_CHILD_TEST(security_manager_73_app_label_monitor_different_users) {
204
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";
211
212     SynchronizationPipe s_pipe;
213
214     pid_t pid = fork();
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);
228         waitPid(pid);
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);
241         s_pipe.wait(); //B
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
247         s_pipe.post(); //C
248     }
249 }
250
251 RUNNER_CHILD_TEST(security_manager_74_app_label_monitor_relabel_changes_1) {
252
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";
260
261     int pipefd[2];
262     RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
263     SynchronizationPipe s_pipe;
264
265     pid_t pid = fork();
266     if (pid != 0) { //parent process
267         FdUniquePtr pipeptr(pipefd + 1);
268         close(pipefd[0]);
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);
282         waitPid(pid);
283     } else { //child process
284         setCaps("all=eip");
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);
288         close(pipefd[1]);
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);
295         s_pipe.wait(); //A
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
302         s_pipe.post(); //B
303     }
304 }
305
306 RUNNER_CHILD_TEST(security_manager_75_app_label_monitor_relabel_changes_2) {
307
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";
316
317     int pipefd[2];
318     RUNNER_ASSERT_MSG((pipe(pipefd) != -1), "pipe failed");
319     SynchronizationPipe s_pipe;
320
321     pid_t pid = fork();
322     if (pid != 0) { //parent process
323         FdUniquePtr pipeptr(pipefd + 1);
324         close(pipefd[0]);
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);
338         waitPid(pid);
339     } else { //child process
340         setCaps("all=eip");
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);
344         close(pipefd[1]);
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);
351         s_pipe.wait(); //A
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
359         s_pipe.post(); //B
360     }
361 }