CKM: CC mode uses user label to read & write keys.
[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_ERRNO_MSG(fstat(fd1, &fs1) == 0, "fstat failed");
68     RUNNER_ASSERT_ERRNO_MSG(fstat(fd2, &fs2) == 0, "fstat failed");
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_ERRNO_MSG((h1 = mmap(0, fs1.st_size, PROT_READ, MAP_SHARED, fd1, 0 )) != MAP_FAILED,
75                                "mmap failed for fd=" << fd1);
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(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 = nullptr;
132     RUNNER_ASSERT(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(result == 0, "Unable to add modify by empty rules");
138     RUNNER_ASSERT_MSG(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(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 = nullptr;
154     RUNNER_ASSERT(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(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(result == 0, "Unable to modify rule.");
165
166     RUNNER_ASSERT_MSG(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
167     RUNNER_ASSERT_MSG(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 = nullptr;
182     RUNNER_ASSERT(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(result == 0, "Unable to modify rule.");
191     RUNNER_ASSERT_MSG(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
192     RUNNER_ASSERT_MSG(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(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(result == 0, "Unable to modify rule.");
201     RUNNER_ASSERT_MSG(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(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 = nullptr;
216     RUNNER_ASSERT(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(result == 0, "Unable to modify rule.");
224     RUNNER_ASSERT_MSG(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(result == 0, "Unable to modify rule.");
228     RUNNER_ASSERT_MSG(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(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(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 = nullptr;
246     RUNNER_ASSERT(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(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(result == 0, "Unable to modify rule.");
257     RUNNER_ASSERT_MSG(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(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(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 = nullptr;
275     RUNNER_ASSERT(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(result == 0, "Unable to modify rule.");
283     RUNNER_ASSERT_MSG(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(result == 0, "Unable to modify rule.");
287     RUNNER_ASSERT_MSG(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(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(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 = nullptr;
306
307     for (i = 0; i < accessesBasic.size(); ++i) {
308         RUNNER_ASSERT(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(result == 0, "Unable to modify accesses instance");
314         RUNNER_ASSERT_MSG(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
315
316         RUNNER_ASSERT_MSG(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 = nullptr;
332
333     for (i = 0; i < accessesBasic.size(); ++i) {
334         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
335         RUNNER_ASSERT(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(result == 0, "Unable to modify accesses instance");
343         RUNNER_ASSERT_MSG(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(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(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(result == 0, "Revoking subject didn't work.");
354
355         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
356             " Revoke didn't work. Accesses exist.");
357         RUNNER_ASSERT_MSG(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(result == 0, "Revoking subject didn't work.");
364
365         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
366             " Revoke didn't work. Accesses exist.");
367         RUNNER_ASSERT_MSG(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 = nullptr;
381
382     for (i = 0; i < accessesBasic.size(); ++i) {
383         // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
384         RUNNER_ASSERT(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(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(result == 0, "Unable to modify accesses instance");
392         RUNNER_ASSERT_MSG(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(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(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(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(result == 0, "Unable to modify accesses instance");
408         result = smack_accesses_clear(rules_ptr.get());
409         RUNNER_ASSERT_MSG(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(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(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(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(result == 0, "Unable to modify accesses instance");
426         result = smack_accesses_clear(rules_ptr.get());
427         RUNNER_ASSERT_MSG(result == 0, "Clearing rules didn't work.");
428
429         RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
430             " Clear didn't work. Accesses exist.");
431         RUNNER_ASSERT_MSG(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 = nullptr;        //rules prepared in this test case
448     struct smack_accesses *import_test = nullptr;  //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(smack_accesses_new(&rules) == 0);
455     SmackAccessesPtr rules_ptr(rules);
456     RUNNER_ASSERT(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_ERRNO_MSG(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_ERRNO_MSG(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_ERRNO_MSG(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(result == 0, "Unable to add smack rules");
472     result = smack_accesses_add(rules_ptr.get(), "reader", "book", "wx");
473     RUNNER_ASSERT_MSG(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(0 == result, "Unable to modify smack rules");
477
478     result = smack_accesses_save(rules_ptr.get(), fd);
479     RUNNER_ASSERT_MSG(0 == result, "Unable to save smack_accesses instance in file");
480
481     result = lseek(fd, 0, SEEK_SET);
482     RUNNER_ASSERT_ERRNO_MSG(result == 0, "lseek() error");
483     result = smack_accesses_add_from_file(import_ptr.get(), fd);
484     RUNNER_ASSERT_MSG(result == 0, "Unable to import rules from file");
485
486     result = smack_accesses_save(import_ptr.get(), tmp);
487     RUNNER_ASSERT_MSG(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(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(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 = nullptr;        //rules prepared in this test case
512     int result;                                 //for storing functions results
513
514     RUNNER_ASSERT(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(result == 0, "Unable to add smack rules");
520     result = smack_accesses_add(rules_ptr.get(), "reader", "book", "r");
521     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
522     result = smack_accesses_add(rules_ptr.get(), "spy", "book", "rwx");
523     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
524
525     result = smack_accesses_apply(rules_ptr.get());       //applying rules to kernel
526     RUNNER_ASSERT_MSG(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(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(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(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(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(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(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(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(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(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 = nullptr;        //rules prepared in this test case
589     int result;                                 //for storing functions results
590     int expected;
591
592     RUNNER_ASSERT(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(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(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(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(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(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 = nullptr;
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(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(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_ERRNO_MSG(fd >= 0, "Unable to open /proc/self/attr/current");
696     FdUniquePtr fd_ptr(&fd);
697     result = read(fd, buff, B_SIZE);
698     RUNNER_ASSERT_ERRNO_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
699     result = strncmp(buff, def_rule, result);
700     RUNNER_ASSERT_MSG(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(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(result >= 0, "Error in getting self label");
710     result = strcmp(label, "cola");
711     free(label);
712     RUNNER_ASSERT_MSG(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_ERRNO_MSG(result == 0, "lseek() error");
717     result = read(fd, buff, B_SIZE);
718     RUNNER_ASSERT_ERRNO_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
719     result = strncmp(buff, "cola", result);
720     RUNNER_ASSERT_MSG(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     RUNNER_IGNORED_MSG("Upstream does not support label removal yet");
726     const std::string fsLabel = "smack06_setlabel_getlabel_test_0";
727     const std::string fsPath = std::string("/tmp/") + fsLabel;
728
729     const std::string filePath = "file";
730
731     FsLabelManager fs(fsPath, fsLabel);
732     fs.createFile(filePath);
733
734     // reset labels first time
735     fs.testSmackClearLabels(filePath);
736
737     // reset labels second time
738     fs.testSmackClearLabels(filePath);
739 }
740
741 RUNNER_TEST_SMACK(smack06_setlabel_getlabel_test_1)
742 {
743     const std::string fsLabel = "smack06_setlabel_getlabel_test_1";
744     const std::string fsPath = std::string("/tmp/") + fsLabel;
745
746     const char* testLabelAccess = "access";
747     const char* testLabelExec = "exec";
748     const std::string filePath = "file";
749
750     FsLabelManager fs(fsPath, fsLabel);
751     fs.createFile(filePath);
752
753     // set and get labels first time
754     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
755     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
756     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
757     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
758
759     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
760     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
761     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
762     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
763
764     // set and get same labels second time
765     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
766     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
767     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
768     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
769
770     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
771     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
772     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
773     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
774 }
775
776 RUNNER_TEST_SMACK(smack06_setlabel_getlabel_test_2)
777 {
778     RUNNER_IGNORED_MSG("Upstream does not support label removal yet");
779     const std::string fsLabel = "smack06_setlabel_getlabel_test_2";
780     const std::string fsPath = std::string("/tmp/") + fsLabel;
781
782     const char* testLabelAccess = "access";
783     const char* testLabelExec = "exec";
784     const std::string filePath = "file";
785     const std::string linkPath = "link";
786
787     FsLabelManager fs(fsPath, fsLabel);
788     fs.createFile(filePath);
789     fs.createLink(linkPath, filePath);
790
791     // set and get labels for file to which link points
792     fs.testSmackSetLabel(linkPath, testLabelAccess, SMACK_LABEL_ACCESS);
793     fs.testSmackSetLabel(linkPath, testLabelExec, SMACK_LABEL_EXEC);
794     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
795     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
796     fs.testSmackGetLabel(linkPath, testLabelAccess, SMACK_LABEL_ACCESS);
797     fs.testSmackGetLabel(linkPath, testLabelExec, SMACK_LABEL_EXEC);
798
799     // link labels should not be changed
800     fs.testSmackLGetLabel(linkPath, nullptr, SMACK_LABEL_ACCESS);
801     fs.testSmackLGetLabel(linkPath, nullptr, SMACK_LABEL_EXEC);
802 }
803
804 RUNNER_TEST_SMACK(smack06_lsetlabel_lgetlabel_test_1)
805 {
806     const std::string fsLabel = "smack06_lsetlabel_lgetlabel_test_1";
807     const std::string fsPath = std::string("/tmp/") + fsLabel;
808
809     const char* testLabelAccess = "fileAccess";
810     const char* testLabelExec = "fileExec";
811     const char* testLinkLabelAccess = "linkAccess";
812     const char* testLinkLabelExec = "linkExec";
813     const std::string filePath = "file";
814     const std::string linkPath = "link";
815
816     FsLabelManager fs(fsPath, fsLabel);
817     fs.createFile(filePath);
818     fs.createLink(linkPath, filePath);
819
820     // set different labels for link and file
821     fs.testSmackSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
822     fs.testSmackSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
823     fs.testSmackLSetLabel(linkPath, testLinkLabelAccess, SMACK_LABEL_ACCESS);
824     fs.testSmackLSetLabel(linkPath, testLinkLabelExec, SMACK_LABEL_EXEC);
825
826     // get those labels
827     fs.testSmackGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
828     fs.testSmackGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
829     fs.testSmackLGetLabel(linkPath, testLinkLabelAccess, SMACK_LABEL_ACCESS);
830     fs.testSmackLGetLabel(linkPath, testLinkLabelExec, SMACK_LABEL_EXEC);
831 }
832
833 RUNNER_TEST_SMACK(smack06_fsetlabel_fgetlabel_test_1)
834 {
835     const std::string fsLabel = "smack06_fsetlabel_fgetlabel_test_1";
836     const std::string fsPath = std::string("/tmp/") + fsLabel;
837
838     const char* testLabelAccess = "access";
839     const char* testLabelExec = "exec";
840     const std::string filePath = "file";
841
842     FsLabelManager fs(fsPath, fsLabel);
843     fs.createFile(filePath);
844
845     // set and get labels for fd
846     fs.testSmackFSetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
847     fs.testSmackFSetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
848     fs.testSmackFGetLabel(filePath, testLabelAccess, SMACK_LABEL_ACCESS);
849     fs.testSmackFGetLabel(filePath, testLabelExec, SMACK_LABEL_EXEC);
850 }
851
852 RUNNER_TEST_SMACK(smack10_adding_removing_rules)
853 {
854     unsigned int i;
855     int result;
856
857     struct smack_accesses *rules = nullptr;
858
859     for (i = 0; i < accessesBasic.size(); ++i)
860     {
861         // Creating rules
862         RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
863         SmackAccessesPtr rules_ptr(rules);
864
865         // Adding accesses
866         result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
867         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
868
869         // Applying rules
870         result = smack_accesses_apply(rules_ptr.get());
871         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
872
873         // Checking if accesses were created
874         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
875         RUNNER_ASSERT_MSG(result == 1,
876             " Error while checking smack access. Result: " << result);
877
878         // Deleting all rules
879         clean_up();
880     }
881
882     for (i = 0; i < 3; ++i)
883     {
884         // --- Creating rules (r or w or x)
885         RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
886         SmackAccessesPtr rules_ptr(rules);
887
888         // Adding accesses
889         result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
890         RUNNER_ASSERT_MSG(result == 0, "Unable to add rulesBasic. Result: " << result);
891
892         // Applying rules
893         result = smack_accesses_apply(rules_ptr.get());
894         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
895         // Checking if accesses were created
896         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
897         RUNNER_ASSERT_MSG(result == 1,
898             " Error while checking smack access. Result: " << result);
899
900         // Checking if wrong accesses were not created
901         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
902         RUNNER_ASSERT_MSG(result == 0,
903             " Error while checking smack access. Result: " << result);
904
905         // --- Modifying accesses (r for wx or w for rx or x for rw)
906         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
907                 accessesBasic[i + 3].c_str(),accessesBasic[i].c_str());
908         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
909
910         // Applying rules
911         result = smack_accesses_apply(rules_ptr.get());
912         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
913
914         // Checking if accesses were created
915         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
916         RUNNER_ASSERT_MSG(result == 1,
917             " Error while checking smack access. Result: " << result);
918
919         // Checking if wrong accesses were not created
920         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
921         RUNNER_ASSERT_MSG(result == 0,
922             " Error while checking smack access. Result: " << result);
923
924         rules_ptr.release();
925         // --- Creating complementary rules (r or w or x)
926         RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
927         rules_ptr.reset(rules);
928
929         // Adding accesses
930         result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT,
931                 accessesBasic[i].c_str());
932         RUNNER_ASSERT_MSG(result == 0, "Unable to add rulesBasic. Result: " << result);
933
934         // Checking if accesses were created
935         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
936         RUNNER_ASSERT_MSG(result == 1,
937             " Error while checking smack access. Result: " << result);
938
939         // Applying rules
940         result = smack_accesses_apply(rules_ptr.get());
941         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
942
943         // Checking if accesses were created
944         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
945         RUNNER_ASSERT_MSG(result == 1,
946             " Error while checking smack access. Result: " << result);
947
948         // --- Modifying accesses (adding rwx and removing r or w or x)
949         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwx",
950                 accessesBasic[i].c_str());
951         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
952
953         // Applying rules
954         result = smack_accesses_apply(rules_ptr.get());
955         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
956
957         // Checking if accesses were created
958         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
959         RUNNER_ASSERT_MSG(result == 1,
960             " Error while checking smack access. Result: " << result);
961
962         // Checking if wrong accesses were not created
963         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
964         RUNNER_ASSERT_MSG(result == 0,
965             " Error while checking smack access. Result: " << result);
966
967         // --- Adding crossing accesses (rx or rw or wx)
968         result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
969                 accessesBasic[3 + ((i + 1) % 3)].c_str(),"");
970         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
971
972         // Applying rules
973         result = smack_accesses_apply(rules_ptr.get());
974         RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
975
976         // Checking if accesses were created
977         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,
978                 accessesBasic[3 + ((i + 1) % 3)].c_str());
979         RUNNER_ASSERT_MSG(result == 1,
980             " Error while checking smack access. Result: " << result);
981
982         result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
983         RUNNER_ASSERT_MSG(result == 1,
984             " Error while checking smack access. Result: " << result);
985
986         // Deleting all rules
987         result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","rwx");
988         RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
989
990         result = smack_accesses_apply(rules_ptr.get());
991         RUNNER_ASSERT_MSG(result == 0, "Error while checking smack access. Result: " << result);
992
993         // Deleting all rules
994         clean_up();
995     }
996 }
997
998 RUNNER_TEST_SMACK(smack11_saving_loading_rules)
999 {
1000     int result;
1001     int fd;
1002
1003     struct smack_accesses *rules = nullptr;
1004
1005     // Pre-cleanup
1006     removeAccessesAll();
1007
1008     RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
1009     SmackAccessesPtr rules_ptr(rules);
1010
1011     // Loading file with rwxat rules - test_smack_rules_full
1012     fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1013     RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules_full");
1014
1015     // Adding rules from file
1016     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1017     close(fd);
1018     RUNNER_ASSERT_MSG(result == 0, "Error importing accesses from file");
1019
1020     // Applying rules
1021     result = smack_accesses_apply(rules_ptr.get());
1022     RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1023
1024     // Checking rules
1025     result = smack_have_access("test_subject_01", "test_object_02", "rwxat");
1026     RUNNER_ASSERT_MSG(result == 1,
1027         " Error while checking smack accesses.");
1028     result = smack_have_access("test_subject_01", "test_object_03", "rwxat");
1029     RUNNER_ASSERT_MSG(result == 1,
1030         " Error while checking smack accesses.");
1031     result = smack_have_access("test_subject_02", "test_object_01", "rwxat");
1032     RUNNER_ASSERT_MSG(result == 1,
1033         " Error while checking smack accesses.");
1034     result = smack_have_access("test_subject_02", "test_object_02", "rwxat");
1035     RUNNER_ASSERT_MSG(result == 1,
1036         " Error while checking smack accesses.");
1037     result = smack_have_access("test_subject_02", "test_object_03", "rwxat");
1038     RUNNER_ASSERT_MSG(result == 1,
1039         " Error while checking smack accesses.");
1040     result = smack_have_access("test_subject_03", "test_object_01", "rwxat");
1041     RUNNER_ASSERT_MSG(result == 1,
1042         " Error while checking smack accesses.");
1043     result = smack_have_access("test_subject_03", "test_object_02", "rwxat");
1044     RUNNER_ASSERT_MSG(result == 1,
1045         " Error while checking smack accesses.");
1046     result = smack_have_access("test_subject_03", "test_object_03", "rwxat");
1047     RUNNER_ASSERT_MSG(result == 1,
1048         " Error while checking smack accesses.");
1049
1050     // Removing rules
1051     removeAccessesAll();
1052
1053     // Creating rules
1054     rules_ptr.release();
1055     RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
1056     rules_ptr.reset(rules);
1057
1058     // Loading file with partial wrong rules - test_smack_rules2
1059     fd = open("/etc/smack/test_smack_rules2", O_RDONLY, 0644);
1060     RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules2");
1061
1062     // Adding rules from file
1063     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1064     close(fd);
1065     RUNNER_ASSERT_MSG(result == 0, "Error importing accesses from file");
1066
1067     // Applying rules
1068     result = smack_accesses_apply(rules_ptr.get());
1069     RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1070
1071     // Checking rules
1072     RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_01", "test_object_01"),
1073         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1074     result = smack_have_access("test_subject_01", "test_object_02", "rwatl");
1075     RUNNER_ASSERT_MSG(result == 1,
1076         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1077     result = smack_have_access("test_subject_01", "test_object_03", "wat");
1078     RUNNER_ASSERT_MSG(result == 1,
1079         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1080     RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_02", "test_object_01"),
1081         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1082     result = smack_have_access("test_subject_02", "test_object_02", "wa-lt");
1083     RUNNER_ASSERT_MSG(result == 1,
1084         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1085     result = smack_have_access("test_subject_02", "test_object_03", "wr");
1086     RUNNER_ASSERT_MSG(result == 1,
1087         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1088     result = smack_have_access("test_subject_03", "test_object_01", "a");
1089     RUNNER_ASSERT_MSG(result == 1,
1090         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1091     result = smack_have_access("test_subject_03", "test_object_02", "rwat");
1092     RUNNER_ASSERT_MSG(result == 1,
1093         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1094     result = smack_have_access("test_subject_03", "test_object_03", "w---l-");
1095     RUNNER_ASSERT_MSG(result == 1,
1096         " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1097
1098     // Removing rules
1099     removeAccessesAll();
1100
1101     // Creating rules
1102     rules_ptr.release();
1103     RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
1104     rules_ptr.reset(rules);
1105
1106     // Loading file with partial wrong rules - test_smack_rules3
1107     fd = open("/etc/smack/test_smack_rules3", O_RDONLY, 0644);
1108     RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules3");
1109
1110     // Adding rules from file
1111     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1112     close(fd);
1113     RUNNER_ASSERT_MSG(result != 0, "Accesses were loaded from file");
1114
1115     // Removing rules
1116     removeAccessesAll();
1117
1118     // Creating rules
1119     rules_ptr.release();
1120     RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
1121     rules_ptr.reset(rules);
1122
1123     // Loading file with partial wrong rules - test_smack_rules4
1124     fd = open("/etc/smack/test_smack_rules4", O_RDONLY, 0644);
1125     RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules4");
1126
1127     // Adding rules from file
1128     result = smack_accesses_add_from_file(rules_ptr.get(), fd);
1129     close(fd);
1130     RUNNER_ASSERT_MSG(result != 0, "Accesses were loaded from file");
1131
1132     // Removing rules
1133     removeAccessesAll();
1134 }
1135
1136 //int smack_new_label_from_socket(int fd, char **label);
1137
1138
1139 static void smack_set_another_label_for_self(void)
1140 {
1141     static int number = time(nullptr);
1142
1143     number++;
1144     std::string smack_label("s" + std::to_string(number));
1145
1146     int result = smack_set_label_for_self(smack_label.c_str());
1147     RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self(" << smack_label << ") failed");
1148 }
1149
1150 static void smack_unix_sock_server(int sock)
1151 {
1152     int fd, result;
1153     char *label;
1154
1155     alarm(2);
1156     fd = accept(sock, nullptr, nullptr);
1157     alarm(0);
1158     RUNNER_ASSERT_ERRNO(fd >= 0);
1159     FdUniquePtr fd_ptr(&fd);
1160
1161     result = smack_new_label_from_self(&label);
1162     RUNNER_ASSERT_MSG(result >= 0, "smack_new_label_from_self() failed");
1163     CStringPtr label_ptr(label);
1164     result = write(fd, label, strlen(label));
1165     RUNNER_ASSERT_ERRNO_MSG(result == (int)strlen(label), "write() failed");
1166
1167 }
1168
1169 RUNNER_MULTIPROCESS_TEST_SMACK(smack09_new_label_from_socket)
1170 {
1171     int pid;
1172     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1173     unlink(SOCK_PATH);
1174     smack_set_another_label_for_self();
1175     pid = fork();
1176     RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
1177     if (!pid) { /* child process, server */
1178         int sock, result;
1179
1180
1181         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1182         RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
1183         SockUniquePtr sock_ptr(&sock);
1184         result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1185         RUNNER_ASSERT_ERRNO_MSG(result == 0, "bind failed");
1186         result = listen(sock, 1);
1187         RUNNER_ASSERT_ERRNO_MSG(result == 0, "listen failed");
1188         smack_unix_sock_server(sock);
1189
1190         pid = fork();
1191         RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
1192         /*  Test if socket label was unaffected by fork() */
1193         smack_unix_sock_server(sock);
1194         if (!pid) {
1195             usleep (100);
1196             smack_set_another_label_for_self();
1197             smack_unix_sock_server(sock);
1198         }
1199
1200         exit(0);
1201     } else { /* parent process, client */
1202         sleep(1); /* Give server some time to setup listening socket */
1203         for (int i = 0; i < 4; ++i) {
1204             int sock, result;
1205             char smack_label1[SMACK_LABEL_LEN + 1];
1206             char *smack_label2;
1207
1208             sock = socket(AF_UNIX, SOCK_STREAM, 0);
1209             RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
1210             SockUniquePtr sock_ptr(&sock);
1211             result = connect(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1212             RUNNER_ASSERT_ERRNO_MSG(result == 0, "connect failed");
1213             alarm(2);
1214             result = read(sock, smack_label1, SMACK_LABEL_LEN);
1215             alarm(0);
1216             RUNNER_ASSERT_ERRNO_MSG(result >= 0, "read failed");
1217             smack_label1[result] = '\0';
1218             result = smack_new_label_from_socket(sock, &smack_label2);
1219             SmackLabelPtr label2_ptr(smack_label2);
1220             RUNNER_ASSERT_MSG(result >= 0, "smack_label_from_socket failed");
1221             result = strcmp(smack_label1, label2_ptr.get());
1222             if (i < 3)
1223                 RUNNER_ASSERT_MSG(result == 0, "smack labels differ: '" << smack_label1
1224                         << "' != '" << smack_label2 << "' i == " << i);
1225             else
1226                 RUNNER_ASSERT_MSG(result != 0, "smack labels do not differ: '" << smack_label1
1227                         << "' != '" << smack_label2 << "' i == " << i);
1228         }
1229     }
1230 }
1231
1232 void createFileWithLabel(const std::string &filePath, const std::string &fileLabel)
1233 {
1234     //create temporary file and set label for it
1235     mode_t systemMask;
1236
1237     unlink(filePath.c_str());
1238     //allow to create file with 777 rights
1239     systemMask = umask(0000);
1240     int fd = open(filePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
1241     //restore system mask
1242     umask(systemMask);
1243     RUNNER_ASSERT_ERRNO_MSG(fd > -1, "Unable to create file for tests");
1244
1245     //for descriptor protection
1246     FdUniquePtr fd_ptr(&fd);
1247
1248     //change owner and group to user APP
1249     int ret = chown(filePath.c_str(), APP_UID, APP_GID);
1250     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Unable to change file owner");
1251
1252     //set smack label on file
1253     ret = smack_setlabel(filePath.c_str(), fileLabel.c_str(), SMACK_LABEL_ACCESS);
1254     RUNNER_ASSERT_MSG(ret == 0, "Unable to set label for file: " << ret);
1255
1256     char *label = nullptr;
1257     ret = smack_getlabel(filePath.c_str(), &label, SMACK_LABEL_ACCESS);
1258     RUNNER_ASSERT_MSG(ret == 0, "Unable to get label from file");
1259     std::string label_str(label ? label : "");
1260     free(label);
1261     RUNNER_ASSERT_MSG(label_str == fileLabel, "File label not match set label");
1262 }
1263
1264 void prepareEnvironment(const std::string &subject, const std::string &object, const std::string &access)
1265 {
1266     const std::string ruleAll = "x";
1267
1268     SecurityServer::AccessProvider provider(subject);
1269     provider.addObjectRule("User", ruleAll);
1270     provider.addObjectRule(object, access);
1271     provider.applyAndSwithToUser(APP_UID, APP_GID);
1272 }
1273
1274 //- Add "l" rule to system
1275 //
1276 //Should be able to add "l" rule to system
1277 RUNNER_CHILD_TEST_SMACK(smack13_0_checking_laccess_mode_enabled_on_device)
1278 {
1279     std::string selfLabel = "smack13_0";
1280     std::string filename = "smack13_0_file";
1281
1282     //function inside checks if rule exist after add it
1283     SecurityServer::AccessProvider provider(selfLabel);
1284     provider.addObjectRule(filename, "l");
1285     provider.apply();
1286
1287     int ret = smack_have_access(selfLabel.c_str(), filename.c_str(), "l");
1288     RUNNER_ASSERT_MSG(ret == 1, "Error in adding laccess rule - l");
1289 }
1290
1291 //- Create file
1292 //- Set label for file and self
1293 //- Drop privileges
1294 //
1295 //Should have no access due to missing SMACK rule
1296 RUNNER_CHILD_TEST_SMACK(smack13_1_checking_laccess_mode)
1297 {
1298     std::string selfLabel = "smack13_1";
1299     std::string filename = "smack13_1_file";
1300     std::string filePath = testDir + filename;
1301
1302     createFileWithLabel(filePath, filename);
1303     int fd = open(filePath.c_str(), O_RDWR, 0);
1304     FdUniquePtr fd_ptr(&fd);
1305
1306     SecurityServer::AccessProvider provider(selfLabel);
1307     provider.applyAndSwithToUser(APP_UID, APP_GID);
1308
1309     int ret = flock(fd, LOCK_EX | LOCK_NB);
1310     RUNNER_ASSERT_ERRNO_MSG(ret < 0, "Error, able to lock file");
1311     ret = flock(fd, LOCK_UN | LOCK_NB);
1312     RUNNER_ASSERT_ERRNO_MSG(ret < 0, "Error, able to lock file");
1313     ret = flock(fd, LOCK_SH | LOCK_NB);
1314     RUNNER_ASSERT_ERRNO_MSG(ret < 0, "Error, able to lock file");
1315 }
1316
1317 //- Create file
1318 //- Set label for file and self
1319 //- Add SMACK rule "l"
1320 //- Drop privileges
1321 //
1322 //Should be able to lock file even without "w" rule
1323 RUNNER_CHILD_TEST_SMACK(smack13_2_checking_laccess_mode_with_l_rule)
1324 {
1325     std::string selfLabel = "smack13_2";
1326     std::string filename = "smack13_2_file";
1327     std::string filePath = testDir + filename;
1328
1329     createFileWithLabel(filePath, filename);
1330     int fd = open(filePath.c_str(), O_RDWR, 0);
1331     FdUniquePtr fd_ptr(&fd);
1332
1333     prepareEnvironment(selfLabel, filename, "l");
1334
1335     int ret = flock(fd, LOCK_EX | LOCK_NB);
1336     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to exclusive lock file");
1337     ret = flock(fd, LOCK_UN | LOCK_NB);
1338     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to unlock file");
1339     ret = flock(fd, LOCK_SH | LOCK_NB);
1340     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to shared lock file");
1341 }
1342
1343 //- Create file
1344 //- Set label for file and self
1345 //- Add SMACK rule "w"
1346 //- Drop privileges
1347 //
1348 //Should be able to lock file even without "l" rule
1349 RUNNER_CHILD_TEST_SMACK(smack13_3_checking_laccess_mode_with_w_rule)
1350 {
1351     std::string selfLabel = "smack13_3";
1352     std::string filename = "smack13_3_file";
1353     std::string filePath = testDir + filename;
1354
1355     createFileWithLabel(filePath, filename);
1356     int fd = open(filePath.c_str(), O_RDWR, 0);
1357     FdUniquePtr fd_ptr(&fd);
1358
1359     prepareEnvironment(selfLabel, filename, "w");
1360
1361     int ret = flock(fd, LOCK_EX | LOCK_NB);
1362     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to exclusive lock file");
1363     ret = flock(fd, LOCK_UN | LOCK_NB);
1364     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to unlock file");
1365     ret = flock(fd, LOCK_SH | LOCK_NB);
1366     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to shared lock file");
1367 }
1368
1369 //- Create file
1370 //- Set label for file and self
1371 //- Add SMACK rule "rw"
1372 //- Drop privileges
1373 //- Lock file (shared lock)
1374 //- Spawn child process
1375 //- Child tries to lock file (shared)
1376 //
1377 //Child should be able to lock file due to shared lock
1378 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_0_checking_laccess_mode_w_rule_child)
1379 {
1380     std::string selfLabel = "smack13_4_0";
1381     std::string filename = "smack13_4_0_file";
1382     std::string filePath = testDir + filename;
1383
1384     createFileWithLabel(filePath, filename);
1385     int fd = open(filePath.c_str(), O_RDWR);
1386     FdUniquePtr fd_ptr(&fd);
1387     int ret = flock(fd, LOCK_SH | LOCK_NB);
1388     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to shared lock file");
1389
1390     pid_t pid = fork();
1391     if (pid == 0) {
1392         //child process
1393         prepareEnvironment(selfLabel, filename, "rw");
1394
1395         int child_fd = open(filePath.c_str(), O_RDWR);
1396         RUNNER_ASSERT_ERRNO_MSG(child_fd > -1, "Unable to open created file");
1397         //for descriptor protection
1398         FdUniquePtr child_fd_ptr(&child_fd);
1399
1400         ret = flock(child_fd, LOCK_SH | LOCK_NB);
1401         RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to lock file with shared lock");
1402     }
1403 }
1404
1405 //- Create file
1406 //- Set label for file and self
1407 //- Add SMACK rule "l"
1408 //- Drop privileges
1409 //- Lock file (shared lock)
1410 //- Spawn child process
1411 //- Child tries to lock file (shared)
1412 //
1413 //Child should be able to lock file due to shared lock
1414 RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_1_checking_laccess_mode_l_rule_child)
1415 {
1416     std::string selfLabel = "smack13_4_1";
1417     std::string filename = "smack13_4_1_file";
1418     std::string filePath = testDir + filename;
1419
1420     createFileWithLabel(filePath, filename);
1421     int fd = open(filePath.c_str(), O_RDWR);
1422     FdUniquePtr fd_str(&fd);
1423     int ret = flock(fd, LOCK_SH | LOCK_NB);
1424     RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to shared lock file");
1425
1426     pid_t pid = fork();
1427     if (pid == 0) {
1428         //child process
1429         //"r" is only for open in O_RDONLY mode
1430         prepareEnvironment(selfLabel, filename, "rl");
1431
1432         int child_fd = open(filePath.c_str(), O_RDONLY, 0);
1433         RUNNER_ASSERT_ERRNO_MSG(child_fd > -1, "Unable to open created file");
1434         //for descriptor protection
1435         FdUniquePtr child_fd_ptr(&child_fd);
1436
1437         ret = flock(child_fd, LOCK_SH | LOCK_NB);
1438         RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Error, unable to lock file with shared lock");
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_ERRNO_MSG(ret == 0, "Error, unable to exclusive lock file");
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_ERRNO_MSG(child_fd > -1, "Unable to open created file");
1470         //for descriptor protection
1471         FdUniquePtr child_fd_ptr(&child_fd);
1472
1473         ret = flock(child_fd, LOCK_EX | LOCK_NB);
1474         RUNNER_ASSERT_ERRNO_MSG(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_ERRNO_MSG(ret == 0, "Error, unable to exclusive lock file");
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_ERRNO_MSG(child_fd > -1, "Unable to open created file");
1507         //for descriptor protection
1508         FdUniquePtr child_fd_ptr(&child_fd);
1509
1510         ret = flock(child_fd, LOCK_EX | LOCK_NB);
1511         RUNNER_ASSERT_ERRNO_MSG(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 = nullptr;
1537     int result;
1538
1539     //init rules
1540     RUNNER_ASSERT(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(result == 0, "Unable to add smack rules");
1547     result = smack_accesses_add(rules_ptr.get(), "reader", "book", "r");
1548     RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
1549     result = smack_accesses_add(rules_ptr.get(), "spy", "book", "rwx");
1550     RUNNER_ASSERT_MSG(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(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(result == -1, "smack_have_access should return error (SMACK is off)");
1559     result = smack_have_access("reader", "book", "rwx");
1560     RUNNER_ASSERT_MSG(result == -1, "smack_have_access should return error (SMACK is off)");
1561     result = smack_have_access("s02badsubjectlabel", "book", "rwx");
1562     RUNNER_ASSERT_MSG(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(result == -1, "smack_revoke_subject error - subject doesn't exist.");
1567     result = smack_revoke_subject("spy");
1568     RUNNER_ASSERT_MSG(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(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(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(result == -1, "Clearing rules should return error - no SMACK on system.");
1580
1581     result = smack_have_access("writer", "book", "rwx");
1582     RUNNER_ASSERT_MSG(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 = nullptr;
1598
1599     RUNNER_ASSERT(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_ERRNO_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules_full");
1605
1606     //load accesses from file
1607     result = smack_accesses_add_from_file(rules.get(), fd);
1608     close(fd);
1609     RUNNER_ASSERT_MSG(result == 0, "Error while importing accesses from file. Result: " << result);
1610 }
1611
1612 /**
1613  * NOSMACK version of smack05 test. Tests if functions getting, or
1614  * setting self label work correctly (that is, return error).
1615  */
1616 RUNNER_TEST_NOSMACK(smack04_self_label_nosmack)
1617 {
1618     char* label = nullptr;
1619     int result;
1620     int fd;
1621
1622     char buff[SMACK_LABEL_LEN+1];
1623
1624     //smack_new_label_from_self should fail
1625     result = smack_new_label_from_self(&label);
1626     RUNNER_ASSERT_MSG(result == -1, "new_label_from_self should return error (SMACK is off).");
1627     RUNNER_ASSERT_MSG(label == nullptr, "new_label_from_self shouldn't allocate memory to label.");
1628     //We don't need to remember about freeing label - smack_new_label_from_self must return nullptr
1629     //label if it's working properly.
1630
1631     // /proc/self/attr/current shouldn't keep any rules inside
1632     fd = open("/proc/self/attr/current", O_RDONLY, 0644);   //file exists, so it should open
1633     RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "/proc/self/attr/current failed to open");
1634     FdUniquePtr fd_ptr(&fd);
1635
1636     result = read(fd, buff, SMACK_LABEL_LEN);   //however reading it should return error
1637     RUNNER_ASSERT_ERRNO_MSG(result < 0, "Reading /proc/self/attr/current should return error");
1638
1639     //setting label for self should fail
1640     result = smack_set_label_for_self("s04testlabel");
1641     RUNNER_ASSERT_MSG(result == -1, "set_label_for_self should return error (SMACK is off).");
1642
1643     //getting previously set label should also fail
1644     result = smack_new_label_from_self(&label);
1645     RUNNER_ASSERT_MSG(result == -1, "new_label_from_self should return error (SMACK is off).");
1646     RUNNER_ASSERT_MSG(label == nullptr, "new_label_from_self shouldn't allocate memory to label.");
1647
1648     // /proc/self/attr/current still shouldn't keep any rules inside
1649     result = lseek(fd, 0, SEEK_SET);    //going to the file beginning
1650     RUNNER_ASSERT_ERRNO_MSG(result == 0, "lseek() error");
1651
1652     result = read(fd, buff, SMACK_LABEL_LEN);   //however it should return error
1653     RUNNER_ASSERT_ERRNO_MSG(result < 0, "Reading /proc/self/attr/current should return error");
1654 }
1655
1656 /**
1657  * NOSMACK version of smack_accesses_add_modify_x tests.
1658  *
1659  * Because all smack_accesses_add_modify tests are basically the same (all use smack_accesses_apply
1660  * and smack_have_access, which return -1 when SMACK is turned off), it makes much more sense to
1661  * write one test which will create rules using smack_accesses_add_modify and then check if
1662  * smack_accesses_apply and smack_have_access indeed return -1 when SMACK is turned off.
1663  */
1664 RUNNER_TEST_NOSMACK(smack05_accesses_add_modify_nosmack)
1665 {
1666     int result;
1667     smack_accesses* rules = nullptr;
1668
1669     RUNNER_ASSERT(smack_accesses_new(&rules) == 0);
1670
1671     SmackAccessesPtr rules_ptr(rules);
1672
1673     //Not doing clean_up() every RUNNER_ASSERT_MSG - what clean_up does is just a creation of new
1674     //rule struct and removal of currenctly added and applied rules. clean_up() must be done only
1675     //after smack_accesses_apply().
1676     result = smack_accesses_add_modify(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1677     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule. Result: " << result);
1678
1679     result = smack_accesses_add_modify(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1680     RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule. Result: " << result);
1681
1682     result = smack_accesses_apply(rules_ptr.get());
1683     RUNNER_ASSERT_MSG(result == -1,
1684             "smack_accesses_apply should return error (SMACK is off). Result: " << result);
1685
1686     result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
1687     if(result != -1) {
1688         clean_up();
1689         RUNNER_FAIL_MSG("smack_have_access should return error (SMACK is off). Result: "
1690                         << result);
1691     }
1692
1693     clean_up();
1694 }
1695
1696 /**
1697  * NOSMACK version of smack09 test.
1698  *
1699  * This test checks if smack_new_label_from_socket reacts correctly. Since label should be
1700  * acquired from getsockopt, and it should fail, we must only set up socket and call
1701  * smack_new_label_from_socket. It should return error.
1702  */
1703 RUNNER_MULTIPROCESS_TEST_NOSMACK(smack09_new_label_from_socket_nosmack)
1704 {
1705     int pid;
1706     struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1707     unlink(SOCK_PATH);
1708     char* smack_label;
1709
1710     pid = fork();
1711     RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
1712     if (!pid) { //child (server)
1713         int sock, result;
1714         int fd;
1715
1716         //Create new socket
1717         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1718         RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
1719         SockUniquePtr sock_ptr(&sock);
1720
1721         //Bind it to sockaddr
1722         result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1723         RUNNER_ASSERT_ERRNO_MSG(result == 0, "bind failed");
1724
1725         //Prepare for listening
1726         result = listen(sock, 1);
1727         RUNNER_ASSERT_ERRNO_MSG(result == 0, "listen failed");
1728
1729         //Accept client
1730         alarm(2);
1731         fd = accept(sock, nullptr, nullptr);
1732         alarm(0);
1733         RUNNER_ASSERT_ERRNO_MSG(fd >= 0, "Failed when accepting connection from client");
1734         FdUniquePtr fd_ptr(&fd);
1735
1736         //wait for smack_new_label_from_socket execution
1737         usleep(200);
1738
1739         //Close server
1740         exit(0);
1741     }
1742     else { //parent (client)
1743         //Wait a little bit until server is set up
1744         sleep(1);
1745         int sock, result;
1746
1747         //Create socket
1748         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1749         RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
1750         SockUniquePtr sock_ptr(&sock);
1751
1752         //Connect to sockaddr
1753         result = connect(sock, (struct sockaddr*) &sockaddr,
1754                 sizeof(struct sockaddr_un));
1755         RUNNER_ASSERT_ERRNO_MSG(result == 0, "connect failed");
1756
1757         //Try getting label, should fail beacuse getsockopt won't get anything
1758         result = smack_new_label_from_socket(sock, &smack_label);
1759         RUNNER_ASSERT_MSG(result == -1, "smack_new_label_from_socket should fail.");
1760     }
1761 }