Refactor test for smack_*getlabel and smack_*setlabel.
[platform/core/test/security-tests.git] / tests / libsmack-tests / test_cases.cpp
1 /*
2  * Copyright (c) 2012 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 /*
18  * @file        test_cases.cpp
19  * @author      Pawel Polawski (p.polawski@samsung.com)
20  * @author      Jan Olszak (j.olszak@samsung.com)
21  * @author      Zofia Abramowska (z.abramowska@samsung.com)
22  * @version     1.0
23  * @brief       libsmack test runner
24  */
25
26 #include <string>
27 #include <sstream>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <dpl/test/test_runner.h>
31 #include <dpl/test/test_runner_multiprocess.h>
32 #include <dpl/log/log.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/mman.h>
36 #include <sys/smack.h>
37 #include <sys/xattr.h>
38 #include <sys/socket.h>
39 #include <sys/un.h>
40 #include <sys/file.h>
41 #include <sys/wait.h>
42 #include "tests_common.h"
43 #include <access_provider.h>
44 #include <fs_label_manager.h>
45 #include "memory.h"
46
47 const char* const TEST_SUBJECT = "test_subject";
48 const char* const TEST_OBJECT = "test_object";
49 const char* const TEST_OBJECT_2 = "test_object_2";
50
51 const std::string testDir = "/tmp/";
52 const std::vector<std::string> accessesBasic = { "r", "w", "x", "wx", "rx", "rw", "rwx", "rwxat" };
53
54 //This one define is required for sockaddr_un initialization
55 #define SOCK_PATH "/tmp/test-smack-socket"
56
57 int files_compare(int fd1, int fd2)
58 {
59     //for getting files sizes
60     struct stat fs1, fs2;
61
62     //handlers for mmap()
63     void *h1 = MAP_FAILED;
64     void *h2 = MAP_FAILED;
65
66     //getting files information
67     RUNNER_ASSERT_MSG_BT(fstat(fd1, &fs1) == 0, "fstat failed: " << strerror(errno));
68     RUNNER_ASSERT_MSG_BT(fstat(fd2, &fs2) == 0, "fstat failed: " << strerror(errno));
69
70     if (fs1.st_size != fs2.st_size) //if files are identical size will be the same
71         return -1;
72
73     //mapping files to process memory
74     RUNNER_ASSERT_MSG_BT((h1 = mmap(0, fs1.st_size, PROT_READ, MAP_SHARED, fd1, 0 )) != MAP_FAILED,
75             "mmap failed for fd=" << fd1 << " : " << strerror(errno));
76
77     if ((h2 = mmap(0, fs2.st_size, PROT_READ, MAP_SHARED, fd2, 0 )) == MAP_FAILED) {
78         munmap(h1, fs1.st_size);
79         RUNNER_ASSERT_MSG_BT(h2 != MAP_FAILED, "mmap failed for fd=" << fd2
80                                                 << " : " << strerror(errno));
81     }
82
83     int result = memcmp(h1, h2, fs1.st_size);
84     munmap(h1, fs1.st_size);
85     munmap(h2, fs2.st_size);
86
87     return result;
88 }
89
90 RUNNER_TEST_GROUP_INIT(libsmack)
91 /**
92  * Helper method to reset privileges at the begginning of tests.
93  */
94 void clean_up()
95 {
96     smack_revoke_subject(TEST_SUBJECT);
97 }
98
99 /**
100  * Checking if subject has any access to object
101  */
102 bool checkNoAccesses(const char *subject, const char *object)
103 {
104     int result;
105
106     for(const auto &perm : std::vector<std::string> {"r", "w", "a","t", "l"}) {
107         result = smack_have_access(subject, object, perm.c_str());
108         if (result == 1) {
109             return false;
110         }
111     }
112     return true;
113 }
114
115 void removeAccessesAll()
116 {
117     for(int i = 1; i <=3; i++)
118         //smack_revoke_subject will fail, when subject does not exist in kernel
119         //as this function is called at test beginning we cannot check return value
120         smack_revoke_subject(("test_subject_0" + std::to_string(i)).c_str());
121 }
122
123 /**
124  * Add a new access with smack_accesses_add_modify()
125  */
126 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_1){
127     int result;
128
129     clean_up();
130
131     struct smack_accesses *rules = NULL;
132     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
133     SmackAccessesPtr rules_ptr(rules);
134
135     // THE TEST
136     result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"xr","");
137     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify by empty rules");
138     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
139
140     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"xr");
141     RUNNER_ASSERT_MSG_BT(result == 1, "Rule modified (added 'xr'), but no change made.");
142
143     // CLEAN UP
144     clean_up();
145 }
146
147
148 /**
149  * Test if rules are applied in the right order, and modification works.
150  */
151 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_2){
152     int result;
153     struct smack_accesses *rules = NULL;
154     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
155     SmackAccessesPtr rules_ptr(rules);
156
157     clean_up();
158
159     // THE TEST
160     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"r","");
161     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
162
163     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
164     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
165
166     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
167     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 0,
168             "Modification didn't work");
169
170     // CLEAN UP
171     clean_up();
172 }
173
174
175 /**
176  * Test if rules are applied in the right order, and modification works.
177  * Using different smack_accesses list to add and delete.
178  */
179 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_3){
180     int result;
181     struct smack_accesses *rules = NULL;
182     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
183     SmackAccessesPtr rules_ptr(rules);
184
185     clean_up();
186
187     // THE TEST
188     // Add r privilage
189     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"r","");
190     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
191     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
192     RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 1,
193             "Adding privileges didn't work");
194
195     // Revoke r privilege
196     rules_ptr.release();
197     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
198     rules_ptr.reset(rules);
199     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
200     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
201     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
202
203     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
204     RUNNER_ASSERT_MSG_BT(result == 0, "Modification didn't work, rule has still 'r' privileges.");
205
206     // CLEAN UP
207     clean_up();
208 }
209
210 /**
211  * Add a list of privileges and then revoke just ONE of them.
212  */
213 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_4){
214     int result;
215     struct smack_accesses *rules = NULL;
216     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
217     SmackAccessesPtr rules_ptr(rules);
218
219     clean_up();
220
221     // THE TEST
222     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwxat","");
223     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
224     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
225
226     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
227     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
228     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
229
230     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
231     RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
232     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
233     RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
234
235     // CLEAN UP
236     clean_up();
237 }
238
239 /**
240  * Add a list of privileges and then revoke just ONE of them.
241  * Without applying privileges in between those actions.
242  */
243 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_5){
244     int result;
245     struct smack_accesses *rules = NULL;
246     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
247     SmackAccessesPtr rules_ptr(rules);
248
249     clean_up();
250
251     // THE TEST
252     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwxat","");
253     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
254
255     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
256     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
257     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
258
259     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
260     RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
261     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
262     RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
263
264     // CLEAN UP
265     clean_up();
266 }
267
268
269 /**
270  * Add a list of privileges and then revoke just TWO of them.
271  */
272 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_6){
273     int result;
274     struct smack_accesses *rules = NULL;
275     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
276     SmackAccessesPtr rules_ptr(rules);
277
278     clean_up();
279
280     // THE TEST
281     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwt","");
282     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
283     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
284
285     result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"ax","rt");
286     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
287     RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
288
289     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"wax");
290     RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'wax' privileges.");
291     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
292     RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
293
294     // CLEAN UP
295     clean_up();
296 }
297
298 /**
299  * Run smack_accesses_add_modify with the same accesses_add and accesses_del.
300  */
301 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_7){
302     unsigned int i;
303     int result;
304
305     struct smack_accesses *rules = NULL;
306
307     for (i = 0; i < accessesBasic.size(); ++i) {
308         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
309         SmackAccessesPtr rules_ptr(rules);
310
311         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
312                 accessesBasic[i].c_str(), accessesBasic[i].c_str());
313         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
314         RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
315
316         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
317             " Error while checking smack access. Accesses exist.");
318
319         // CLEAN UP
320         clean_up();
321     }
322 }
323
324 /**
325  * Revoke subject with previously added rules and revoke it again.
326  */
327 RUNNER_TEST_SMACK(smack_revoke_subject_test_1){
328     unsigned int i;
329     int result;
330
331     struct smack_accesses *rules = NULL;
332
333     for (i = 0; i < accessesBasic.size(); ++i) {
334         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
335         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
336         SmackAccessesPtr rules_ptr(rules);
337
338         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
339                 accessesBasic[i].c_str(),"");
340         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT_2,
341                 accessesBasic[i].c_str(),"");
342         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
343         RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
344         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
345         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. "
346                 "Rule " << accessesBasic[i].c_str() << " does not exist.");
347         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
348         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. "
349                 "Rule " << accessesBasic[i].c_str() << " does not exist.");
350
351         // Revoking subject
352         result = smack_revoke_subject(TEST_SUBJECT);
353         RUNNER_ASSERT_MSG_BT(result == 0, "Revoking subject didn't work.");
354
355         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
356             " Revoke didn't work. Accesses exist.");
357         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
358             " Revoke didn't work. Accesses exist.");
359
360
361         // Revoking subject again
362         result = smack_revoke_subject(TEST_SUBJECT);
363         RUNNER_ASSERT_MSG_BT(result == 0, "Revoking subject didn't work.");
364
365         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
366             " Revoke didn't work. Accesses exist.");
367         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
368             " Revoke didn't work. Accesses exist.");
369
370     }
371 }
372
373 /**
374  * Clearing accesses
375  */
376 RUNNER_TEST_SMACK(smack_accesses_clear_test_1){
377     unsigned int i;
378     int result;
379
380     struct smack_accesses *rules = NULL;
381
382     for (i = 0; i < accessesBasic.size(); ++i) {
383         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
384         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
385         SmackAccessesPtr rules_ptr(rules);
386         result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
387                 accessesBasic[i].c_str());
388         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
389         result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT_2,
390                 accessesBasic[i].c_str());
391         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
392         RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
393
394         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
395         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule "
396                 << accessesBasic[i].c_str() << " does not exist.");
397         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
398         RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule "
399                 << accessesBasic[i].c_str() << " does not exist.");
400
401         // Creating and clearing rules with TEST_OBJECT
402         rules_ptr.release();
403         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
404         rules_ptr.reset(rules);
405         result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
406                 accessesBasic[i].c_str());
407         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
408         result = smack_accesses_clear(rules_ptr.get());
409         RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work.");
410
411         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
412         RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work. Rule "
413                 << accessesBasic[i].c_str() << " does exist.");
414         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
415         RUNNER_ASSERT_MSG_BT(result == 1, "Clearing rules didn't work. Rule "
416                 << accessesBasic[i].c_str() << " does not exist.");
417
418         // Creating and clearing rules with TEST_OBJECT
419         rules_ptr.release();
420         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
421         rules_ptr.reset(rules);
422
423         result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT_2,
424                 accessesBasic[i].c_str());
425         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
426         result = smack_accesses_clear(rules_ptr.get());
427         RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work.");
428
429         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
430             " Clear didn't work. Accesses exist.");
431         RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
432             " Clear didn't work. Accesses exist.");
433     }
434 }
435
436 RUNNER_TEST(smack01_storing_and_restoring_rules)
437 {
438     /*
439      * author: Pawel Polawski
440      * test: smack_accesses_new, smack_accesses_add, smack_accesses_add_modify, smack_accesses_add_from_file,
441      *       smack_accesses_free, smack_accesses_save
442      * description: This test case will create structure holding SMACK rules and add new one to it. Next rules will be
443      *              stored and restored from file.
444      * expect: Rules created and stored in file should be identical to predefined template.
445      */
446
447     struct smack_accesses *rules = NULL;        //rules prepared in this test case
448     struct smack_accesses *import_test = NULL;  //rules imported from file
449
450     int result;             //result of each operation to be tested by RUNNER_ASSERT
451     int fd, tmp, sample;    //file descripptors for save / restore rules tests
452
453     //int smack_accesses_new(struct smack_accesses **accesses);
454     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
455     SmackAccessesPtr rules_ptr(rules);
456     RUNNER_ASSERT_BT(smack_accesses_new(&import_test) == 0);
457     SmackAccessesPtr import_ptr(import_test);
458
459     //opening files
460     fd = open("/tmp/smack01_rules", O_RDWR | O_CREAT | O_TRUNC, 0644);  //for export prepared rules
461     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to create /tmp/smack01_rules");
462     FdUniquePtr fd_ptr(&fd);
463     tmp = open("/tmp/smack01_tmp", O_RDWR | O_CREAT | O_TRUNC, 0644);   //for import rules exported before
464     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to create /tmp/smack01_tmp");
465     FdUniquePtr tmp_ptr(&tmp);
466     sample = open("/etc/smack/test_smack_rules", O_RDONLY, 0644);             //reference preinstalled rules
467     RUNNER_ASSERT_MSG_BT(sample >= 0, "Unable to open /etc/smack/test_smack_rules");
468     FdUniquePtr sample_ptr(&sample);
469
470     result = smack_accesses_add(rules_ptr.get(), "writer", "book", "rw");
471     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
472     result = smack_accesses_add(rules_ptr.get(), "reader", "book", "wx");
473     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
474
475     result = smack_accesses_add_modify(rules_ptr.get(), "reader", "book", "r", "wx");
476     RUNNER_ASSERT_MSG_BT(0 == result, "Unable to modify smack rules");
477
478     result = smack_accesses_save(rules_ptr.get(), fd);
479     RUNNER_ASSERT_MSG_BT(0 == result, "Unable to save smack_accesses instance in file");
480
481     result = lseek(fd, 0, SEEK_SET);
482     RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error");
483     result = smack_accesses_add_from_file(import_ptr.get(), fd);
484     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to import rules from file");
485
486     result = smack_accesses_save(import_ptr.get(), tmp);
487     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to save smack_accesses instance in file");
488
489     //comparing rules saved in file, restored from it and stored one more time
490     result = files_compare(fd, tmp);
491     RUNNER_ASSERT_MSG_BT(result == 0, "No match in stored and restored rules");
492
493     //comparing rules stored in file with reference preinstalled rules
494     result = files_compare(tmp, sample);
495     RUNNER_ASSERT_MSG_BT(result == 0, "No match in stored rules and pattern file");
496 }
497
498 RUNNER_TEST_SMACK(smack02_aplying_rules_into_kernel)
499 {
500     /*
501      * author: Pawel Polawski
502      * test: smack_accesses_apply, smack_have_access, smack_revoke_subject, smack_accesses_clear, smack_accesses_new,
503      *       smack_accesses_add, smack_accesses_free
504      * description: In this test case aplying rules to kernel will be tested. After that function for test
505      *              accesses will be used.
506      * expect: In case of correct rules access should be granted.
507      */
508
509     //CAP_MAC_ADMIN needed for process to be able to change rules in kernel (apllying, removing)
510
511     struct smack_accesses *rules = NULL;        //rules prepared in this test case
512     int result;                                 //for storing functions results
513
514     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
515     SmackAccessesPtr rules_ptr(rules);
516
517     //adding test rules to struct
518     result = smack_accesses_add(rules_ptr.get(), "writer", "book", "rwx");
519     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
520     result = smack_accesses_add(rules_ptr.get(), "reader", "book", "r");
521     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
522     result = smack_accesses_add(rules_ptr.get(), "spy", "book", "rwx");
523     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
524
525     result = smack_accesses_apply(rules_ptr.get());       //applying rules to kernel
526     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to apply rules into kernel");
527
528     //should have access - rule exist
529     result = smack_have_access("spy", "book", "rwx");
530     RUNNER_ASSERT_MSG_BT(result == 1, "Error while checking Smack access");
531     //should have no access - wrong rule, should be "r" only
532     result = smack_have_access("reader", "book", "rwx");
533     RUNNER_ASSERT_MSG_BT(result == 0, "Error while checking Smack access");
534     //should have no access - rule not exist
535     result = smack_have_access("s02badsubjectlabel", "book", "rwx");
536     RUNNER_ASSERT_MSG_BT(result == 0, "Error while checking Smack access");
537
538     //this subject do not exist in kernel rules
539     result = smack_revoke_subject("s02nonexistinglabel");
540     RUNNER_ASSERT_MSG_BT(result == 0, "Error in removing not existing subject from kernel");
541     result = smack_revoke_subject("spy");       //this subject exist in kernel rules
542     RUNNER_ASSERT_MSG_BT(result == 0, "Error in removing existing subject from kernel");
543
544     //testing access after revoke_subject() from kernel
545     result = smack_have_access("spy", "book", "rwx");
546     //now spy should have no access
547     RUNNER_ASSERT_MSG_BT(result == 0, "Error in acces aplied to kernel");
548
549     //for create new rule as a consequence of use accesses_clear() below
550     result = smack_accesses_add(rules_ptr.get(), "s02subjectlabel", "book", "rwx");
551     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
552
553     //"spy" removed before by using smack_revoke_subject()
554     result = smack_accesses_clear(rules_ptr.get());
555     RUNNER_ASSERT_MSG_BT(result == 0, "Error in clearing rules in kernel");
556
557     //testing acces after acces_clear()
558     result = smack_have_access("writer", "book", "rwx");
559     //now writer also should have no access
560     RUNNER_ASSERT_MSG_BT(result == 0, "Error in acces aplied to kernel");
561
562 }
563
564 //pairs of rules for test with mixed cases, different length and mixed order
565 std::vector< std::vector<std::string> > correct_rules = {
566     { "reader1",  "-",                "------" },
567     { "reader2",  "--------",         "------" },
568     { "reader3",  "RwXaTl",           "rwxatl" },
569     { "reader4",  "RrrXXXXTTT",       "r-x-t-" },
570     { "reader5",  "-r-w-a-t-",        "rw-at-" },
571     { "reader6",  "",                 "------" },
572     { "reader7",  "xa--Rt---W--L",    "rwxatl" },
573 };
574
575 RUNNER_TEST_SMACK(smack03_mixed_rule_string_add)
576 {
577     /*
578      * author: Pawel Polawski
579      * test: smack_have_access, smack_accesses_new, smack_accesses_add, smack_accesses_apply, smack_accesses_free
580      * description: In thist test case rules based on mixed string are added to kernel.
581      *              Strings are presented above and contains lower / upper case alpha, numbers and special signs.
582      * expect: Rules should be parsed correct and aplied to kernel.
583      */
584
585     //In thist test case mixed string are used as rules applied to kernel, next they are
586     //readed and compared with correct form of rules
587
588     struct smack_accesses *rules = NULL;        //rules prepared in this test case
589     int result;                                 //for storing functions results
590     int expected;
591
592     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
593     SmackAccessesPtr rules_ptr(rules);
594
595     //adding test rules with mixed string
596     for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
597         //using mixed rules from table
598         result = smack_accesses_add(rules_ptr.get(),
599                                     (*rule)[0].c_str(),
600                                     "book",
601                                     (*rule)[1].c_str());
602         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
603     }
604
605     //clearing
606     //FIXME: Using clear() here can cover error in accesses_apply() function
607     //result = smack_accesses_clear(rules);
608     //RUNNER_ASSERT_MSG_BT(result == 0, "Error in clearing rules in kernel");
609
610     //applying rules to kernel
611     result = smack_accesses_apply(rules_ptr.get());
612     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to apply rules into kernel");
613
614     //checking accesses using normal rules
615     for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
616         if ((*rule)[2] == "------")
617             expected = 0;
618         else
619             expected = 1;
620         //using normal rules from table
621         result = smack_have_access((*rule)[0].c_str(),
622                                    "book",
623                                    (*rule)[2].c_str());
624         RUNNER_ASSERT_MSG_BT(result == expected, "Error while checking Smack access");
625     }
626 }
627
628 RUNNER_TEST_SMACK(smack04_mixed_rule_string_have_access)
629 {
630     /*
631      * author: Pawel Polawski
632      * test: smack_have_access
633      * description: In this test case we testing aplied before SMACK rules and comparing them using mixed strings.
634      * expect: Subjects should have accesses to the objects.
635      */
636
637     //In this test case we checking previous aplied rules but for compare mixed strings are used
638
639     int result;
640     int expected;
641
642     //rules were added in previous RUNNER_TEST section
643     //checking accesses using mixed rules
644     for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
645         if ((*rule)[2] == "------")
646             expected = 0;
647         else
648             expected = 1;
649         //using mixed rules from table
650         result = smack_have_access((*rule)[0].c_str(),
651                                    "book",
652                                    (*rule)[1].c_str());
653         RUNNER_ASSERT_MSG_BT(result == expected, "Error while checking Smack access");
654     }
655 }
656
657 //RUNNER_TEST(smackXX_accesses_add_modify)
658 //{
659 //IDEAS FOR TESTS
660 // - what if we want to apply rule that is already in kernel?
661 // - tests for smack_accesses_add_modify() + smack_have_access() (check if add_modify sets the proper rule)
662 // - smack_accesses_add_modify("subject", "object", "rwx", "rwx") should create empty rule
663 //}
664
665 RUNNER_TEST_SMACK(smack05_self_label)
666 {
667     /*
668      * author: Pawel Polawski
669      * test: smack_set_label_for_self, smack_new_label_from_self
670      * description: In this test case process test it own default label. Next label is changed
671      *              and tested one more time if change was successfull.
672      * expect: Proces should have default "-" label and can change it to the oter one.
673      */
674
675     //In this test case process will manipulate it own label
676
677     char *label = NULL;
678     int result;
679     int fd;
680
681     const int B_SIZE = 8;
682     char buff[B_SIZE];
683
684     const char *def_rule = "_";
685
686     result = smack_new_label_from_self(&label);
687     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in getting self label");
688     //comparing this label with default one "_"
689     result = strcmp(label, def_rule);
690     free(label);
691     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong default process label");
692
693     //comparing this rule with received from /proc/self/attr/current
694     fd = open("/proc/self/attr/current", O_RDONLY, 0644);
695     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /proc/self/attr/current");
696     FdUniquePtr fd_ptr(&fd);
697     result = read(fd, buff, B_SIZE);
698     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in reading from file /proc/self/attr/current");
699     result = strncmp(buff, def_rule, result);
700     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong default process rule");
701
702     //now time for setting labels:
703
704     result = smack_set_label_for_self("cola");
705     RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting self label");
706
707     //checking new label using smack function
708     result = smack_new_label_from_self(&label);
709     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in getting self label");
710     result = strcmp(label, "cola");
711     free(label);
712     RUNNER_ASSERT_MSG_BT(result == 0, "Wrong process label");
713
714     //checking new label using /proc/self/attr/current
715     result = lseek(fd, 0, SEEK_SET);    //going to the file beginning
716     RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error");
717     result = read(fd, buff, B_SIZE);
718     RUNNER_ASSERT_MSG_BT(result >= 0, "Error in reading from file /proc/self/attr/current");
719     result = strncmp(buff, "cola", result);
720     RUNNER_ASSERT_MSG_BT(result == 0, "Proces rule in /proc/self/attr/current other than set");
721 }
722
723 RUNNER_TEST_SMACK(smack06_setlabel_getlabel_test_0)
724 {
725     const std::string fsLabel = "smack06_setlabel_getlabel_test_0";
726     const std::string fsPath = std::string("/tmp/") + fsLabel;
727
728     const std::string filePath = "file";
729
730     FsLabelManager fs(fsPath, fsLabel);
731     fs.createFile(filePath);
732
733     // reset labels first time
734     fs.testSmackClearLabels(filePath);
735
736     // reset labels second time
737     fs.testSmackClearLabels(filePath);
738 }
739
740 RUNNER_TEST_SMACK(smack06_setlabel_getlabel_test_1)
741 {
742     const std::string fsLabel = "smack06_setlabel_getlabel_test_1";
743     const std::string fsPath = std::string("/tmp/") + fsLabel;
744
745     const char* testLabelAccess = "access";
746     const char* testLabelExec = "exec";
747     const std::string filePath = "file";
748
749     FsLabelManager fs(fsPath, fsLabel);
750     fs.createFile(filePath);
751
752     // set and get labels first time
753     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
754     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
755     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
756     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
757
758     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
759     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
760     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
761     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
762
763     // set and get same labels second time
764     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
765     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
766     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
767     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
768
769     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
770     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
771     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
772     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
773 }
774
775 RUNNER_TEST_SMACK(smack06_setlabel_getlabel_test_2)
776 {
777     const std::string fsLabel = "smack06_setlabel_getlabel_test_2";
778     const std::string fsPath = std::string("/tmp/") + fsLabel;
779
780     const char* testLabelAccess = "access";
781     const char* testLabelExec = "exec";
782     const std::string filePath = "file";
783     const std::string linkPath = "link";
784
785     FsLabelManager fs(fsPath, fsLabel);
786     fs.createFile(filePath);
787     fs.createLink(linkPath, filePath);
788
789     // set and get labels for file to which link points
790     fs.testSmackSetLabel(linkPath, testLabelAccess, SMACK_LABEL_ACCESS);
791     fs.testSmackSetLabel(linkPath, testLabelExec, SMACK_LABEL_EXEC);
792     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
793     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
794     fs.testSmackGetLabel(linkPath, testLabelAccess, SMACK_LABEL_ACCESS);
795     fs.testSmackGetLabel(linkPath, testLabelExec, SMACK_LABEL_EXEC);
796
797     // link labels should not be changed
798     fs.testSmackLGetLabel(linkPath, NULL, SMACK_LABEL_ACCESS);
799     fs.testSmackLGetLabel(linkPath, NULL, SMACK_LABEL_EXEC);
800 }
801
802 RUNNER_TEST_SMACK(smack06_lsetlabel_lgetlabel_test_1)
803 {
804     const std::string fsLabel = "smack06_lsetlabel_lgetlabel_test_1";
805     const std::string fsPath = std::string("/tmp/") + fsLabel;
806
807     const char* testLabelAccess = "fileAccess";
808     const char* testLabelExec = "fileExec";
809     const char* testLinkLabelAccess = "linkAccess";
810     const char* testLinkLabelExec = "linkExec";
811     const std::string filePath = "file";
812     const std::string linkPath = "link";
813
814     FsLabelManager fs(fsPath, fsLabel);
815     fs.createFile(filePath);
816     fs.createLink(linkPath, filePath);
817
818     // set different labels for link and file
819     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
820     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
821     fs.testSmackLSetLabel(linkPath, testLinkLabelAccess, SMACK_LABEL_ACCESS);
822     fs.testSmackLSetLabel(linkPath, testLinkLabelExec, SMACK_LABEL_EXEC);
823
824     // get those labels
825     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
826     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
827     fs.testSmackLGetLabel(linkPath, testLinkLabelAccess, SMACK_LABEL_ACCESS);
828     fs.testSmackLGetLabel(linkPath, testLinkLabelExec, SMACK_LABEL_EXEC);
829 }
830
831 RUNNER_TEST_SMACK(smack06_fsetlabel_fgetlabel_test_1)
832 {
833     const std::string fsLabel = "smack06_fsetlabel_fgetlabel_test_1";
834     const std::string fsPath = std::string("/tmp/") + fsLabel;
835
836     const char* testLabelAccess = "access";
837     const char* testLabelExec = "exec";
838     const std::string filePath = "file";
839
840     FsLabelManager fs(fsPath, fsLabel);
841     fs.createFile(filePath);
842
843     // set and get labels for fd
844     fs.testSmackFSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
845     fs.testSmackFSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
846     fs.testSmackFGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
847     fs.testSmackFGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
848 }
849
850 RUNNER_TEST_SMACK(smack10_adding_removing_rules)
851 {
852     unsigned int i;
853     int result;
854
855     struct smack_accesses *rules = NULL;
856
857     for (i = 0; i < accessesBasic.size(); ++i)
858     {
859         // Creating rules
860         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
861         SmackAccessesPtr rules_ptr(rules);
862
863         // Adding accesses
864         result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
865         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
866
867         // Applying rules
868         result = smack_accesses_apply(rules_ptr.get());
869         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
870
871         // Checking if accesses were created
872         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
873         RUNNER_ASSERT_MSG_BT(result == 1,
874             " Error while checking smack access. Result: " << result);
875
876         // Deleting all rules
877         clean_up();
878     }
879
880     for (i = 0; i < 3; ++i)
881     {
882         // --- Creating rules (r or w or x)
883         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
884         SmackAccessesPtr rules_ptr(rules);
885
886         // Adding accesses
887         result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
888         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add rulesBasic. Result: " << result);
889
890         // Applying rules
891         result = smack_accesses_apply(rules_ptr.get());
892         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
893         // Checking if accesses were created
894         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
895         RUNNER_ASSERT_MSG_BT(result == 1,
896             " Error while checking smack access. Result: " << result);
897
898         // Checking if wrong accesses were not created
899         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
900         RUNNER_ASSERT_MSG_BT(result == 0,
901             " Error while checking smack access. Result: " << result);
902
903         // --- Modifying accesses (r for wx or w for rx or x for rw)
904         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
905                 accessesBasic[i + 3].c_str(),accessesBasic[i].c_str());
906         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
907
908         // Applying rules
909         result = smack_accesses_apply(rules_ptr.get());
910         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
911
912         // Checking if accesses were created
913         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
914         RUNNER_ASSERT_MSG_BT(result == 1,
915             " Error while checking smack access. Result: " << result);
916
917         // Checking if wrong accesses were not created
918         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
919         RUNNER_ASSERT_MSG_BT(result == 0,
920             " Error while checking smack access. Result: " << result);
921
922         rules_ptr.release();
923         // --- Creating complementary rules (r or w or x)
924         RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
925         rules_ptr.reset(rules);
926
927         // Adding accesses
928         result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT,
929                 accessesBasic[i].c_str());
930         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add rulesBasic. Result: " << result);
931
932         // Checking if accesses were created
933         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
934         RUNNER_ASSERT_MSG_BT(result == 1,
935             " Error while checking smack access. Result: " << result);
936
937         // Applying rules
938         result = smack_accesses_apply(rules_ptr.get());
939         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
940
941         // Checking if accesses were created
942         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
943         RUNNER_ASSERT_MSG_BT(result == 1,
944             " Error while checking smack access. Result: " << result);
945
946         // --- Modifying accesses (adding rwx and removing r or w or x)
947         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwx",
948                 accessesBasic[i].c_str());
949         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
950
951         // Applying rules
952         result = smack_accesses_apply(rules_ptr.get());
953         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
954
955         // Checking if accesses were created
956         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
957         RUNNER_ASSERT_MSG_BT(result == 1,
958             " Error while checking smack access. Result: " << result);
959
960         // Checking if wrong accesses were not created
961         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
962         RUNNER_ASSERT_MSG_BT(result == 0,
963             " Error while checking smack access. Result: " << result);
964
965         // --- Adding crossing accesses (rx or rw or wx)
966         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
967                 accessesBasic[3 + ((i + 1) % 3)].c_str(),"");
968         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
969
970         // Applying rules
971         result = smack_accesses_apply(rules_ptr.get());
972         RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
973
974         // Checking if accesses were created
975         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,
976                 accessesBasic[3 + ((i + 1) % 3)].c_str());
977         RUNNER_ASSERT_MSG_BT(result == 1,
978             " Error while checking smack access. Result: " << result);
979
980         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
981         RUNNER_ASSERT_MSG_BT(result == 1,
982             " Error while checking smack access. Result: " << result);
983
984         // Deleting all rules
985         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","rwx");
986         RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
987
988         result = smack_accesses_apply(rules_ptr.get());
989         RUNNER_ASSERT_MSG_BT(result == 0, "Error while checking smack access. Result: " << result);
990
991         // Deleting all rules
992         clean_up();
993     }
994 }
995
996 RUNNER_TEST_SMACK(smack11_saving_loading_rules)
997 {
998     int result;
999     int fd;
1000
1001     struct smack_accesses *rules = NULL;
1002
1003     // Pre-cleanup
1004     removeAccessesAll();
1005
1006     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
1007     SmackAccessesPtr rules_ptr(rules);
1008
1009     // Loading file with rwxat rules - test_smack_rules_full
1010     fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1011     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules_full");
1012
1013     // Adding rules from file
1014     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1015     close(fd);
1016     RUNNER_ASSERT_MSG_BT(result == 0, "Error importing accesses from file");
1017
1018     // Applying rules
1019     result = smack_accesses_apply(rules_ptr.get());
1020     RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1021
1022     // Checking rules
1023     result = smack_have_access("test_subject_01", "test_object_02", "rwxat");
1024     RUNNER_ASSERT_MSG_BT(result == 1,
1025         " Error while checking smack accesses.");
1026     result = smack_have_access("test_subject_01", "test_object_03", "rwxat");
1027     RUNNER_ASSERT_MSG_BT(result == 1,
1028         " Error while checking smack accesses.");
1029     result = smack_have_access("test_subject_02", "test_object_01", "rwxat");
1030     RUNNER_ASSERT_MSG_BT(result == 1,
1031         " Error while checking smack accesses.");
1032     result = smack_have_access("test_subject_02", "test_object_02", "rwxat");
1033     RUNNER_ASSERT_MSG_BT(result == 1,
1034         " Error while checking smack accesses.");
1035     result = smack_have_access("test_subject_02", "test_object_03", "rwxat");
1036     RUNNER_ASSERT_MSG_BT(result == 1,
1037         " Error while checking smack accesses.");
1038     result = smack_have_access("test_subject_03", "test_object_01", "rwxat");
1039     RUNNER_ASSERT_MSG_BT(result == 1,
1040         " Error while checking smack accesses.");
1041     result = smack_have_access("test_subject_03", "test_object_02", "rwxat");
1042     RUNNER_ASSERT_MSG_BT(result == 1,
1043         " Error while checking smack accesses.");
1044     result = smack_have_access("test_subject_03", "test_object_03", "rwxat");
1045     RUNNER_ASSERT_MSG_BT(result == 1,
1046         " Error while checking smack accesses.");
1047
1048     // Removing rules
1049     removeAccessesAll();
1050
1051     // Creating rules
1052     rules_ptr.release();
1053     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
1054     rules_ptr.reset(rules);
1055
1056     // Loading file with partial wrong rules - test_smack_rules2
1057     fd = open("/etc/smack/test_smack_rules2", O_RDONLY, 0644);
1058     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules2");
1059
1060     // Adding rules from file
1061     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1062     close(fd);
1063     RUNNER_ASSERT_MSG_BT(result == 0, "Error importing accesses from file");
1064
1065     // Applying rules
1066     result = smack_accesses_apply(rules_ptr.get());
1067     RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
1068
1069     // Checking rules
1070     RUNNER_ASSERT_MSG_BT(checkNoAccesses("test_subject_01", "test_object_01"),
1071         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1072     result = smack_have_access("test_subject_01", "test_object_02", "rwatl");
1073     RUNNER_ASSERT_MSG_BT(result == 1,
1074         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1075     result = smack_have_access("test_subject_01", "test_object_03", "wat");
1076     RUNNER_ASSERT_MSG_BT(result == 1,
1077         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1078     RUNNER_ASSERT_MSG_BT(checkNoAccesses("test_subject_02", "test_object_01"),
1079         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1080     result = smack_have_access("test_subject_02", "test_object_02", "wa-lt");
1081     RUNNER_ASSERT_MSG_BT(result == 1,
1082         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1083     result = smack_have_access("test_subject_02", "test_object_03", "wr");
1084     RUNNER_ASSERT_MSG_BT(result == 1,
1085         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1086     result = smack_have_access("test_subject_03", "test_object_01", "a");
1087     RUNNER_ASSERT_MSG_BT(result == 1,
1088         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1089     result = smack_have_access("test_subject_03", "test_object_02", "rwat");
1090     RUNNER_ASSERT_MSG_BT(result == 1,
1091         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1092     result = smack_have_access("test_subject_03", "test_object_03", "w---l-");
1093     RUNNER_ASSERT_MSG_BT(result == 1,
1094         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1095
1096     // Removing rules
1097     removeAccessesAll();
1098
1099     // Creating rules
1100     rules_ptr.release();
1101     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
1102     rules_ptr.reset(rules);
1103
1104     // Loading file with partial wrong rules - test_smack_rules3
1105     fd = open("/etc/smack/test_smack_rules3", O_RDONLY, 0644);
1106     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules3");
1107
1108     // Adding rules from file
1109     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1110     close(fd);
1111     RUNNER_ASSERT_MSG_BT(result != 0, "Accesses were loaded from file");
1112
1113     // Removing rules
1114     removeAccessesAll();
1115
1116     // Creating rules
1117     rules_ptr.release();
1118     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
1119     rules_ptr.reset(rules);
1120
1121     // Loading file with partial wrong rules - test_smack_rules4
1122     fd = open("/etc/smack/test_smack_rules4", O_RDONLY, 0644);
1123     RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules4");
1124
1125     // Adding rules from file
1126     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1127     close(fd);
1128     RUNNER_ASSERT_MSG_BT(result != 0, "Accesses were loaded from file");
1129
1130     // Removing rules
1131     removeAccessesAll();
1132 }
1133
1134 //int smack_new_label_from_socket(int fd, char **label);
1135
1136
1137 static void smack_set_another_label_for_self(void)
1138 {
1139     static int number = time(NULL);
1140
1141     number++;
1142     std::string smack_label("s" + std::to_string(number));
1143
1144     int result = smack_set_label_for_self(smack_label.c_str());
1145     RUNNER_ASSERT_MSG_BT(result == 0, "smack_set_label_for_self(" << smack_label << ") failed");
1146 }
1147
1148 static void smack_unix_sock_server(int sock)
1149 {
1150     int fd, result;
1151     char *label;
1152
1153     alarm(2);
1154     fd = accept(sock, NULL, NULL);
1155     alarm(0);
1156     RUNNER_ASSERT_BT(fd >= 0);
1157     FdUniquePtr fd_ptr(&fd);
1158
1159     result = smack_new_label_from_self(&label);
1160     RUNNER_ASSERT_MSG_BT(result >= 0, "smack_new_label_from_self() failed");
1161     CStringPtr label_ptr(label);
1162     result = write(fd, label, strlen(label));
1163     RUNNER_ASSERT_MSG_BT(result == (int)strlen(label), "write() failed");
1164
1165 }
1166
1167 RUNNER_MULTIPROCESS_TEST_SMACK(smack09_new_label_from_socket)
1168 {
1169     int pid;
1170     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1171     unlink(SOCK_PATH);
1172     smack_set_another_label_for_self();
1173     pid = fork();
1174     RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
1175     if (!pid) { /* child process, server */
1176         int sock, result;
1177
1178
1179         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1180         RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1181         SockUniquePtr sock_ptr(&sock);
1182         result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1183         RUNNER_ASSERT_MSG_BT(result == 0, "bind failed: " << strerror(errno));
1184         result = listen(sock, 1);
1185         RUNNER_ASSERT_MSG_BT(result == 0, "listen failed: " << strerror(errno));
1186         smack_unix_sock_server(sock);
1187
1188         pid = fork();
1189         RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
1190         /*  Test if socket label was unaffected by fork() */
1191         smack_unix_sock_server(sock);
1192         if (!pid) {
1193             usleep (100);
1194             smack_set_another_label_for_self();
1195             smack_unix_sock_server(sock);
1196         }
1197
1198         exit(0);
1199     } else { /* parent process, client */
1200         sleep(1); /* Give server some time to setup listening socket */
1201         for (int i = 0; i < 4; ++i) {
1202             int sock, result;
1203             char smack_label1[SMACK_LABEL_LEN + 1];
1204             char *smack_label2;
1205
1206             sock = socket(AF_UNIX, SOCK_STREAM, 0);
1207             RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1208             SockUniquePtr sock_ptr(&sock);
1209             result = connect(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1210             RUNNER_ASSERT_MSG_BT(result == 0, "connect failed: " << strerror(errno));
1211             alarm(2);
1212             result = read(sock, smack_label1, SMACK_LABEL_LEN);
1213             alarm(0);
1214             RUNNER_ASSERT_MSG_BT(result >= 0, "read failed: " << strerror(errno));
1215             smack_label1[result] = '\0';
1216             result = smack_new_label_from_socket(sock, &smack_label2);
1217             SmackLabelPtr label2_ptr(smack_label2);
1218             RUNNER_ASSERT_MSG_BT(result >= 0, "smack_label_from_socket failed");
1219             result = strcmp(smack_label1, label2_ptr.get());
1220             if (i < 3)
1221                 RUNNER_ASSERT_MSG_BT(result == 0, "smack labels differ: '" << smack_label1
1222                         << "' != '" << smack_label2 << "' i == " << i);
1223             else
1224                 RUNNER_ASSERT_MSG_BT(result != 0, "smack labels do not differ: '" << smack_label1
1225                         << "' != '" << smack_label2 << "' i == " << i);
1226         }
1227     }
1228 }
1229
1230 void createFileWithLabel(const std::string &filePath, const std::string &fileLabel)
1231 {
1232     //create temporary file and set label for it
1233     mode_t systemMask;
1234
1235     unlink(filePath.c_str());
1236     //allow to create file with 777 rights
1237     systemMask = umask(0000);
1238     int fd = open(filePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
1239     //restore system mask
1240     umask(systemMask);
1241     RUNNER_ASSERT_MSG_BT(fd > -1, "Unable to create file for tests: " << strerror(errno));
1242
1243     //for descriptor protection
1244     FdUniquePtr fd_ptr(&fd);
1245
1246     //change owner and group to user APP
1247     int ret = chown(filePath.c_str(), APP_UID, APP_GID);
1248     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to change file owner: " << strerror(errno));
1249
1250     //set smack label on file
1251     ret = smack_setlabel(filePath.c_str(), fileLabel.c_str(), SMACK_LABEL_ACCESS);
1252     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to set label for file: " << ret);
1253
1254     char *label = NULL;
1255     ret = smack_getlabel(filePath.c_str(), &label, SMACK_LABEL_ACCESS);
1256     RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to get label from file");
1257     std::string label_str(label ? label : "");
1258     free(label);
1259     RUNNER_ASSERT_MSG_BT(label_str == fileLabel, "File label not match set label");
1260 }
1261
1262 void prepareEnvironment(const std::string &subject, const std::string &object, const std::string &access)
1263 {
1264     const std::string ruleAll = "x";
1265
1266     SecurityServer::AccessProvider provider(subject);
1267     provider.addObjectRule("User", ruleAll);
1268     provider.addObjectRule(object, access);
1269     provider.applyAndSwithToUser(APP_UID, APP_GID);
1270 }
1271
1272 //- Add "l" rule to system
1273 //
1274 //Should be able to add "l" rule to system
1275 RUNNER_CHILD_TEST_SMACK(smack13_0_checking_laccess_mode_enabled_on_device)
1276 {
1277     std::string selfLabel = "smack13_0";
1278     std::string filename = "smack13_0_file";
1279
1280     //function inside checks if rule exist after add it
1281     SecurityServer::AccessProvider provider(selfLabel);
1282     provider.addObjectRule(filename, "l");
1283     provider.apply();
1284
1285     int ret = smack_have_access(selfLabel.c_str(), filename.c_str(), "l");
1286     RUNNER_ASSERT_MSG_BT(ret == 1, "Error in adding laccess rule - l");
1287 }
1288
1289 //- Create file
1290 //- Set label for file and self
1291 //- Drop privileges
1292 //
1293 //Should have no access due to missing SMACK rule
1294 RUNNER_CHILD_TEST_SMACK(smack13_1_checking_laccess_mode)
1295 {
1296     std::string selfLabel = "smack13_1";
1297     std::string filename = "smack13_1_file";
1298     std::string filePath = testDir + filename;
1299
1300     createFileWithLabel(filePath, filename);
1301     int fd = open(filePath.c_str(), O_RDWR, 0);
1302     FdUniquePtr fd_ptr(&fd);
1303
1304     SecurityServer::AccessProvider provider(selfLabel);
1305     provider.applyAndSwithToUser(APP_UID, APP_GID);
1306
1307     int ret = flock(fd, LOCK_EX | LOCK_NB);
1308     RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
1309     ret = flock(fd, LOCK_UN | LOCK_NB);
1310     RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
1311     ret = flock(fd, LOCK_SH | LOCK_NB);
1312     RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
1313 }
1314
1315 //- Create file
1316 //- Set label for file and self
1317 //- Add SMACK rule "l"
1318 //- Drop privileges
1319 //
1320 //Should be able to lock file even without "w" rule
1321 RUNNER_CHILD_TEST_SMACK(smack13_2_checking_laccess_mode_with_l_rule)
1322 {
1323     std::string selfLabel = "smack13_2";
1324     std::string filename = "smack13_2_file";
1325     std::string filePath = testDir + filename;
1326
1327     createFileWithLabel(filePath, filename);
1328     int fd = open(filePath.c_str(), O_RDWR, 0);
1329     FdUniquePtr fd_ptr(&fd);
1330
1331     prepareEnvironment(selfLabel, filename, "l");
1332
1333     int ret = flock(fd, LOCK_EX | LOCK_NB);
1334     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1335     ret = flock(fd, LOCK_UN | LOCK_NB);
1336     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to unlock file: " << strerror(errno));
1337     ret = flock(fd, LOCK_SH | LOCK_NB);
1338     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1339 }
1340
1341 //- Create file
1342 //- Set label for file and self
1343 //- Add SMACK rule "w"
1344 //- Drop privileges
1345 //
1346 //Should be able to lock file even without "l" rule
1347 RUNNER_CHILD_TEST_SMACK(smack13_3_checking_laccess_mode_with_w_rule)
1348 {
1349     std::string selfLabel = "smack13_3";
1350     std::string filename = "smack13_3_file";
1351     std::string filePath = testDir + filename;
1352
1353     createFileWithLabel(filePath, filename);
1354     int fd = open(filePath.c_str(), O_RDWR, 0);
1355     FdUniquePtr fd_ptr(&fd);
1356
1357     prepareEnvironment(selfLabel, filename, "w");
1358
1359     int ret = flock(fd, LOCK_EX | LOCK_NB);
1360     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1361     ret = flock(fd, LOCK_UN | LOCK_NB);
1362     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to unlock file: " << strerror(errno));
1363     ret = flock(fd, LOCK_SH | LOCK_NB);
1364     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1365 }
1366
1367 //- Create file
1368 //- Set label for file and self
1369 //- Add SMACK rule "rw"
1370 //- Drop privileges
1371 //- Lock file (shared lock)
1372 //- Spawn child process
1373 //- Child tries to lock file (shared)
1374 //
1375 //Child should be able to lock file due to shared lock
1376 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_0_checking_laccess_mode_w_rule_child)
1377 {
1378     std::string selfLabel = "smack13_4_0";
1379     std::string filename = "smack13_4_0_file";
1380     std::string filePath = testDir + filename;
1381
1382     createFileWithLabel(filePath, filename);
1383     int fd = open(filePath.c_str(), O_RDWR);
1384     FdUniquePtr fd_ptr(&fd);
1385     int ret = flock(fd, LOCK_SH | LOCK_NB);
1386     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1387
1388     pid_t pid = fork();
1389     if (pid == 0) {
1390         //child process
1391         prepareEnvironment(selfLabel, filename, "rw");
1392
1393         int child_fd = open(filePath.c_str(), O_RDWR);
1394         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1395         //for descriptor protection
1396         FdUniquePtr child_fd_ptr(&child_fd);
1397
1398         ret = flock(child_fd, LOCK_SH | LOCK_NB);
1399         RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to lock file with shared lock: "
1400                           << strerror(errno));
1401     }
1402 }
1403
1404 //- Create file
1405 //- Set label for file and self
1406 //- Add SMACK rule "l"
1407 //- Drop privileges
1408 //- Lock file (shared lock)
1409 //- Spawn child process
1410 //- Child tries to lock file (shared)
1411 //
1412 //Child should be able to lock file due to shared lock
1413 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_1_checking_laccess_mode_l_rule_child)
1414 {
1415     std::string selfLabel = "smack13_4_1";
1416     std::string filename = "smack13_4_1_file";
1417     std::string filePath = testDir + filename;
1418
1419     createFileWithLabel(filePath, filename);
1420     int fd = open(filePath.c_str(), O_RDWR);
1421     FdUniquePtr fd_str(&fd);
1422     int ret = flock(fd, LOCK_SH | LOCK_NB);
1423     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
1424
1425     pid_t pid = fork();
1426     if (pid == 0) {
1427         //child process
1428         //"r" is only for open in O_RDONLY mode
1429         prepareEnvironment(selfLabel, filename, "rl");
1430
1431         int child_fd = open(filePath.c_str(), O_RDONLY, 0);
1432         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1433         //for descriptor protection
1434         FdUniquePtr child_fd_ptr(&child_fd);
1435
1436         ret = flock(child_fd, LOCK_SH | LOCK_NB);
1437         RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to lock file with shared lock: "
1438                           << strerror(errno));
1439     }
1440 }
1441
1442 //- Create file
1443 //- Set label for file and self
1444 //- Add SMACK rule "rw"
1445 //- Drop privileges
1446 //- Lock file (exclusive lock)
1447 //- Spawn child process
1448 //- Child tries to lock file (exclusive / shared)
1449 //
1450 //Child should not be able to lock file due to exclusive lock
1451 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_2_checking_laccess_mode_w_rule_child)
1452 {
1453     std::string selfLabel = "smack13_4_2";
1454     std::string filename = "smack13_4_2_file";
1455     std::string filePath = testDir + filename;
1456
1457     createFileWithLabel(filePath, filename);
1458     int fd = open(filePath.c_str(), O_RDWR);
1459     FdUniquePtr fd_ptr(&fd);
1460     int ret = flock(fd, LOCK_EX | LOCK_NB);
1461     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1462
1463     pid_t pid = fork();
1464     if (pid == 0) {
1465         //child process
1466         prepareEnvironment(selfLabel, filename, "rw");
1467
1468         int child_fd = open(filePath.c_str(), O_RDWR, 0);
1469         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1470         //for descriptor protection
1471         FdUniquePtr child_fd_ptr(&child_fd);
1472
1473         ret = flock(child_fd, LOCK_EX | LOCK_NB);
1474         RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file with exclusive lock");
1475     }
1476 }
1477
1478 //- Create file
1479 //- Set label for file and self
1480 //- Add SMACK rule "l"
1481 //- Drop privileges
1482 //- Lock file (exclusive lock)
1483 //- Spawn child process
1484 //- Child tries to lock file (exclusive / shared)
1485 //
1486 //Child should not be able to lock file due to exclusive lock
1487 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_3_checking_laccess_mode_l_rule_child)
1488 {
1489     std::string selfLabel = "smack13_4_3";
1490     std::string filename = "smack13_4_3_file";
1491     std::string filePath = testDir + filename;
1492
1493     createFileWithLabel(filePath, filename);
1494     int fd = open(filePath.c_str(), O_RDWR, 0);
1495     FdUniquePtr fd_ptr(&fd);
1496     int ret = flock(fd, LOCK_EX | LOCK_NB);
1497     RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
1498
1499     pid_t pid = fork();
1500     if (pid == 0) {
1501         //child process
1502         //"r" is only for open in O_RDONLY mode
1503         prepareEnvironment(selfLabel, filename, "rl");
1504
1505         int child_fd = open(filePath.c_str(), O_RDONLY, 0);
1506         RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
1507         //for descriptor protection
1508         FdUniquePtr child_fd_ptr(&child_fd);
1509
1510         ret = flock(child_fd, LOCK_EX | LOCK_NB);
1511         RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file with eclusive lock");
1512     }
1513 }
1514
1515
1516 /////////////////////////////////////////
1517 //////NOSMACK ENVIRONMENT TESTS//////////
1518 /////////////////////////////////////////
1519
1520 /**
1521  * NOSMACK version of smack02 test. Functions, that should return error instead of success:
1522  * - smack_accesses_apply
1523  * - smack_have_access
1524  * - smack_revoke_subject
1525  * - smack_acceesses_clear
1526  *
1527  * Tests smack03, smack04, smack10, smack_accesses_clear, smack_revoke_subject all use functions
1528  * tested in smack02 test. Results from those functions (smack_have_access, smack_accesses_apply,
1529  * smack_accesses_clear, smack_revoke_subject) would be the same as in this test. Tests mentioned
1530  * above doesn't make much sense on NOSMACK environment when test smack02 exists and passes
1531  * correctly, thus those tests are are not implemented.
1532  */
1533 RUNNER_TEST_NOSMACK(smack02_aplying_rules_into_kernel_nosmack)
1534 {
1535
1536     smack_accesses *rules = NULL;
1537     int result;
1538
1539     //init rules
1540     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
1541     //pass rules to unique_ptr
1542     SmackAccessesPtr rules_ptr(rules);
1543
1544     //adding test rules to struct (same as SMACK version of smack02 test)
1545     result = smack_accesses_add(rules_ptr.get(), "writer", "book", "rwx");
1546     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1547     result = smack_accesses_add(rules_ptr.get(), "reader", "book", "r");
1548     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1549     result = smack_accesses_add(rules_ptr.get(), "spy", "book", "rwx");
1550     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1551
1552     //applying rules to kernel (should fail)
1553     result = smack_accesses_apply(rules_ptr.get());
1554     RUNNER_ASSERT_MSG_BT(result == -1, "Unable to apply rules into kernel");
1555
1556     //calls from SMACK version of this test - all should fail because of SMACK being turned off
1557     result = smack_have_access("spy", "book", "rwx");
1558     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
1559     result = smack_have_access("reader", "book", "rwx");
1560     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
1561     result = smack_have_access("s02badsubjectlabel", "book", "rwx");
1562     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
1563
1564     //testing subject revoking - should return error (no accesses applied = no subjects to revoke)
1565     result = smack_revoke_subject("s02nonexistinglabel");
1566     RUNNER_ASSERT_MSG_BT(result == -1, "smack_revoke_subject error - subject doesn't exist.");
1567     result = smack_revoke_subject("spy");
1568     RUNNER_ASSERT_MSG_BT(result == -1, "smack_revoke_subject error - subject doesn't exist.");
1569
1570     //after revoking smack_have_access still should return error
1571     result = smack_have_access("spy", "book", "rwx");
1572     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off).");
1573
1574     result = smack_accesses_add(rules_ptr.get(), "s02subjectlabel", "book", "rwx");
1575     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
1576
1577     //smack_accesses_clear should return error aswell
1578     result = smack_accesses_clear(rules_ptr.get());
1579     RUNNER_ASSERT_MSG_BT(result == -1, "Clearing rules should return error - no SMACK on system.");
1580
1581     result = smack_have_access("writer", "book", "rwx");
1582     RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off).");
1583 }
1584
1585 /**
1586  * NOSMACK version of smack11 test. Tests functions:
1587  * - smack_accesses_add_from_file
1588  *
1589  * Since other SMACK functions were tested in smack02 test, the only function needed to be checked
1590  * is applying rules loaded from file.
1591  */
1592 RUNNER_TEST_NOSMACK(smack03_saving_loading_rules_nosmack)
1593 {
1594     int result;
1595     int fd;
1596
1597     smack_accesses* tmp = NULL;
1598
1599     RUNNER_ASSERT_BT(smack_accesses_new(&tmp) == 0);
1600     SmackAccessesPtr rules(tmp);
1601
1602     //open file with rules
1603     fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1604     RUNNER_ASSERT_MSG_BT(fd >= 0,
1605             "Unable to open /etc/smack/test_smack_rules_full. Errno: " << strerror(errno));
1606
1607     //load accesses from file
1608     result = smack_accesses_add_from_file(rules.get(), fd);
1609     close(fd);
1610     RUNNER_ASSERT_MSG_BT(result == 0, "Error while importing accesses from file. Result: " << result);
1611 }
1612
1613 /**
1614  * NOSMACK version of smack05 test. Tests if functions getting, or
1615  * setting self label work correctly (that is, return error).
1616  */
1617 RUNNER_TEST_NOSMACK(smack04_self_label_nosmack)
1618 {
1619     char* label = NULL;
1620     int result;
1621     int fd;
1622
1623     char buff[SMACK_LABEL_LEN+1];
1624
1625     //smack_new_label_from_self should fail
1626     result = smack_new_label_from_self(&label);
1627     RUNNER_ASSERT_MSG_BT(result == -1, "new_label_from_self should return error (SMACK is off).");
1628     RUNNER_ASSERT_MSG_BT(label == NULL, "new_label_from_self shouldn't allocate memory to label.");
1629     //We don't need to remember about freeing label - smack_new_label_from_self must return NULL
1630     //label if it's working properly.
1631
1632     // /proc/self/attr/current shouldn't keep any rules inside
1633     fd = open("/proc/self/attr/current", O_RDONLY, 0644);   //file exists, so it should open
1634     RUNNER_ASSERT_MSG_BT(fd >= 0, "/proc/self/attr/current failed to open.");
1635     FdUniquePtr fd_ptr(&fd);
1636
1637     result = read(fd, buff, SMACK_LABEL_LEN);   //however reading it should return error
1638     RUNNER_ASSERT_MSG_BT(result < 0, "Reading /proc/self/attr/current should return error.");
1639
1640     //setting label for self should fail
1641     result = smack_set_label_for_self("s04testlabel");
1642     RUNNER_ASSERT_MSG_BT(result == -1, "set_label_for_self should return error (SMACK is off).");
1643
1644     //getting previously set label should also fail
1645     result = smack_new_label_from_self(&label);
1646     RUNNER_ASSERT_MSG_BT(result == -1, "new_label_from_self should return error (SMACK is off).");
1647     RUNNER_ASSERT_MSG_BT(label == NULL, "new_label_from_self shouldn't allocate memory to label.");
1648
1649     // /proc/self/attr/current still shouldn't keep any rules inside
1650     result = lseek(fd, 0, SEEK_SET);    //going to the file beginning
1651     RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error.");
1652
1653     result = read(fd, buff, SMACK_LABEL_LEN);   //however it should return error
1654     RUNNER_ASSERT_MSG_BT(result < 0, "Reading /proc/self/attr/current should return error.");
1655 }
1656
1657 /**
1658  * NOSMACK version of smack_accesses_add_modify_x tests.
1659  *
1660  * Because all smack_accesses_add_modify tests are basically the same (all use smack_accesses_apply
1661  * and smack_have_access, which return -1 when SMACK is turned off), it makes much more sense to
1662  * write one test which will create rules using smack_accesses_add_modify and then check if
1663  * smack_accesses_apply and smack_have_access indeed return -1 when SMACK is turned off.
1664  */
1665 RUNNER_TEST_NOSMACK(smack05_accesses_add_modify_nosmack)
1666 {
1667     int result;
1668     smack_accesses* rules = NULL;
1669
1670     RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
1671
1672     SmackAccessesPtr rules_ptr(rules);
1673
1674     //Not doing clean_up() every RUNNER_ASSERT_MSG - what clean_up does is just a creation of new
1675     //rule struct and removal of currenctly added and applied rules. clean_up() must be done only
1676     //after smack_accesses_apply().
1677     result = smack_accesses_add_modify(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1678     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule. Result: " << result);
1679
1680     result = smack_accesses_add_modify(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1681     RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule. Result: " << result);
1682
1683     result = smack_accesses_apply(rules_ptr.get());
1684     RUNNER_ASSERT_MSG_BT(result == -1,
1685             "smack_accesses_apply should return error (SMACK is off). Result: " << result);
1686
1687     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
1688     if(result != -1) {
1689         clean_up();
1690         RUNNER_ASSERT_MSG_BT(false,
1691                 "smack_have_access should return error (SMACK is off). Result: " << result);
1692     }
1693
1694     clean_up();
1695 }
1696
1697 /**
1698  * NOSMACK version of smack09 test.
1699  *
1700  * This test checks if smack_new_label_from_socket reacts correctly. Since label should be
1701  * acquired from getsockopt, and it should fail, we must only set up socket and call
1702  * smack_new_label_from_socket. It should return error.
1703  */
1704 RUNNER_MULTIPROCESS_TEST_NOSMACK(smack09_new_label_from_socket_nosmack)
1705 {
1706     int pid;
1707     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1708     unlink(SOCK_PATH);
1709     char* smack_label;
1710
1711     pid = fork();
1712     RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
1713     if (!pid) { //child (server)
1714         int sock, result;
1715         int fd;
1716
1717         //Create new socket
1718         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1719         RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1720         SockUniquePtr sock_ptr(&sock);
1721
1722         //Bind it to sockaddr
1723         result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1724         RUNNER_ASSERT_MSG_BT(result == 0, "bind failed: " << strerror(errno));
1725
1726         //Prepare for listening
1727         result = listen(sock, 1);
1728         RUNNER_ASSERT_MSG_BT(result == 0, "listen failed: " << strerror(errno));
1729
1730         //Accept client
1731         alarm(2);
1732         fd = accept(sock, NULL, NULL);
1733         alarm(0);
1734         RUNNER_ASSERT_MSG_BT(fd >= 0, "Failed when accepting connection from client.");
1735         FdUniquePtr fd_ptr(&fd);
1736
1737         //wait for smack_new_label_from_socket execution
1738         usleep(200);
1739
1740         //Close server
1741         exit(0);
1742     }
1743     else { //parent (client)
1744         //Wait a little bit until server is set up
1745         sleep(1);
1746         int sock, result;
1747
1748         //Create socket
1749         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1750         SockUniquePtr sock_ptr(&sock);
1751         RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
1752
1753         //Connect to sockaddr
1754         result = connect(sock, (struct sockaddr*) &sockaddr,
1755                 sizeof(struct sockaddr_un));
1756         RUNNER_ASSERT_MSG_BT(result == 0, "connect failed: " << strerror(errno));
1757
1758         //Try getting label, should fail beacuse getsockopt won't get anything
1759         result = smack_new_label_from_socket(sock, &smack_label);
1760         RUNNER_ASSERT_MSG_BT(result == -1, "smack_new_label_from_socket should fail.");
1761     }
1762 }