2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @file test_cases.cpp
19 * @author Pawel Polawski (p.polawski@samsung.com)
20 * @author Jan Olszak (j.olszak@samsung.com)
22 * @brief libprivilege test runer
29 #include <dpl/test/test_runner.h>
30 #include <dpl/log/log.h>
31 #include <sys/types.h>
34 #include <sys/smack.h>
35 #include <sys/xattr.h>
36 #include <sys/socket.h>
39 #include "tests_common.h"
41 #define TEST_SUBJECT "test_subject"
42 #define TEST_OBJECT "test_oject"
43 #define TEST_OBJECT_2 "test_oject_2"
45 #define SOCK_PATH "/tmp/test-smack-socket"
47 std::vector<std::string> accessesBasic = { "r", "w", "x", "wx", "rx", "rw", "rwx", "rwxat" };
49 typedef std::unique_ptr<smack_accesses, std::function<void(smack_accesses*)> > AccessesUniquePtr;
54 int files_compare(int fd1, int fd2)
58 //for getting files sizes
62 void *h1 = MAP_FAILED;
63 void *h2 = MAP_FAILED;
65 //getting files information
66 if (fstat(fd1, &fs1) == -1) {
70 if (fstat(fd2, &fs2) == -1) {
75 if (fs1.st_size != fs2.st_size) //if files are identical size will be the same
78 //mapping files to process memory
79 if ((h1 = mmap(0, fs1.st_size, PROT_READ, MAP_SHARED, fd1, 0 )) == MAP_FAILED) {
83 if ((h2 = mmap(0, fs2.st_size, PROT_READ, MAP_SHARED, fd2, 0 )) == MAP_FAILED) {
88 result = memcmp(h1, h2, fs1.st_size);
90 //cleaning after mmap()
93 munmap(h2, fs2.st_size);
95 munmap(h1, fs1.st_size);
101 RUNNER_TEST_GROUP_INIT(libsmack)
103 * Helper method to reset privileges at the begginning of tests.
107 struct smack_accesses *rules = NULL;
108 int result = smack_accesses_new(&rules);
109 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
112 smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","rwxat");
113 smack_accesses_apply(rules);
114 smack_accesses_free(rules);
117 RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") != 1, "Rule has previous privileges after cleaning up!");
118 RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"w") != 1, "Rule has previous privileges after cleaning up!");
119 RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"x") != 1, "Rule has previous privileges after cleaning up!");
120 RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"a") != 1, "Rule has previous privileges after cleaning up!");
121 RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"t") != 1, "Rule has previous privileges after cleaning up!");
125 * Checking if subject has any access to object
127 bool checkNoAccesses(const char *subject, const char *object)
130 result = smack_have_access(subject, object,"r");
134 result = smack_have_access(subject, object,"w");
138 result = smack_have_access(subject, object,"x");
142 result = smack_have_access(subject, object,"a");
146 result = smack_have_access(subject, object,"t");
153 void removeAccessesAll()
155 struct smack_accesses *rules = NULL;
156 int result = smack_accesses_new(&rules);
157 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
159 result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_01", "", "rxwat");
160 result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_02", "", "rxwat");
161 result = smack_accesses_add_modify(rules, "test_subject_01", "test_object_03", "", "rxwat");
162 result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_01", "", "rxwat");
163 result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_02", "", "rxwat");
164 result = smack_accesses_add_modify(rules, "test_subject_02", "test_object_03", "", "rxwat");
165 result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_01", "", "rxwat");
166 result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_02", "", "rxwat");
167 result = smack_accesses_add_modify(rules, "test_subject_03", "test_object_03", "", "rxwat");
169 smack_accesses_apply(rules);
170 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
171 smack_accesses_free(rules);
176 * Add a new access with smack_accesses_add_modify()
178 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_1){
183 struct smack_accesses *rules = NULL;
184 result = smack_accesses_new(&rules);
187 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"xr","");
188 RUNNER_ASSERT_MSG(result == 0, "Unable to add modify by empty rules");
189 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
191 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"xr");
192 RUNNER_ASSERT_MSG(result == 1, "Rule modified (added 'xr'), but no change made.");
196 smack_accesses_free(rules);
201 * Test if rules are applied in the right order, and modification works.
203 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_2){
205 struct smack_accesses *rules = NULL;
206 result = smack_accesses_new(&rules);
207 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
212 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"r","");
213 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
215 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
216 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
218 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
219 RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 0, "Modification didn't work");
223 smack_accesses_free(rules);
228 * Test if rules are applied in the right order, and modification works.
229 * Using different smack_accesses list to add and delete.
231 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_3){
233 struct smack_accesses *rules = NULL;
234 result = smack_accesses_new(&rules);
235 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
241 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"r","");
242 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
243 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
244 RUNNER_ASSERT_MSG(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 1, "Adding privileges didn't work");
245 smack_accesses_free(rules);
247 // Revoke r privilege
248 result = smack_accesses_new(&rules);
249 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
250 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
251 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
252 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
254 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
255 RUNNER_ASSERT_MSG(result == 0, "Modification didn't work, rule has still 'r' privileges.");
259 smack_accesses_free(rules);
263 * Add a list of privileges and then revoke just ONE of them.
265 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_4){
267 struct smack_accesses *rules = NULL;
268 result = smack_accesses_new(&rules);
269 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
274 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwxat","");
275 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
276 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
278 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
279 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
280 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
282 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
283 RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
284 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
285 RUNNER_ASSERT_MSG(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
289 smack_accesses_free(rules);
293 * Add a list of privileges and then revoke just ONE of them.
294 * Without applying privileges in between those actions.
296 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_5){
298 struct smack_accesses *rules = NULL;
299 result = smack_accesses_new(&rules);
300 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
305 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwxat","");
306 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
308 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","r");
309 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
310 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
312 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
313 RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
314 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
315 RUNNER_ASSERT_MSG(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
319 smack_accesses_free(rules);
324 * Add a list of privileges and then revoke just TWO of them.
326 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_6){
328 struct smack_accesses *rules = NULL;
329 result = smack_accesses_new(&rules);
330 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
335 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"rwt","");
336 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
337 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
339 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"ax","rt");
340 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule.");
341 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
343 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"wax");
344 RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule should have 'wax' privileges.");
345 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
346 RUNNER_ASSERT_MSG(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
350 smack_accesses_free(rules);
354 * Run smack_accesses_add_modify with the same accesses_add and accesses_del.
356 RUNNER_TEST_SMACK(smack_accesses_add_modify_test_7){
360 struct smack_accesses *rules = NULL;
362 for (i = 0; i < accessesBasic.size(); ++i) {
363 result = smack_accesses_new(&rules);
364 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
366 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str(),accessesBasic[i].c_str());
367 RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
368 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
370 RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
371 " Error while checking smack access. Accesses exist.");
375 smack_accesses_free(rules);
380 * Revoke subject with previously added rules and revoke it again.
382 RUNNER_TEST_SMACK(smack_revoke_subject_test_1){
386 struct smack_accesses *rules = NULL;
388 for (i = 0; i < accessesBasic.size(); ++i) {
389 // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
390 result = smack_accesses_new(&rules);
391 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
392 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str(),"");
393 result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str(),"");
394 RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
395 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
396 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
397 RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
398 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
399 RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
402 result = smack_revoke_subject(TEST_SUBJECT);
403 RUNNER_ASSERT_MSG(result == 0, "Revoking subject didn't work.");
405 RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
406 " Revoke didn't work. Accesses exist.");
407 RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
408 " Revoke didn't work. Accesses exist.");
411 // Revoking subject again
412 result = smack_revoke_subject(TEST_SUBJECT);
413 RUNNER_ASSERT_MSG(result == 0, "Revoking subject didn't work.");
415 RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
416 " Revoke didn't work. Accesses exist.");
417 RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
418 " Revoke didn't work. Accesses exist.");
420 smack_accesses_free(rules);
427 RUNNER_TEST_SMACK(smack_accesses_clear_test_1){
431 struct smack_accesses *rules = NULL;
433 for (i = 0; i < accessesBasic.size(); ++i) {
434 // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
435 result = smack_accesses_new(&rules);
436 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
437 result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
438 RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
439 result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
440 RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
441 RUNNER_ASSERT_MSG(smack_accesses_apply(rules) == 0, "Unable to apply rules");
443 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
444 RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
445 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
446 RUNNER_ASSERT_MSG(result == 1, "Modification didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
448 smack_accesses_free(rules);
450 // Creating and clearing rules with TEST_OBJECT
451 result = smack_accesses_new(&rules);
452 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
453 result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
454 RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
455 result = smack_accesses_clear(rules);
456 RUNNER_ASSERT_MSG(result == 0, "Clearing rules didn't work.");
458 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
459 RUNNER_ASSERT_MSG(result == 0, "Clearing rules didn't work. Rule " << accessesBasic[i].c_str() << " does exist.");
460 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
461 RUNNER_ASSERT_MSG(result == 1, "Clearing rules didn't work. Rule " << accessesBasic[i].c_str() << " does not exist.");
463 smack_accesses_free(rules);
465 // Creating and clearing rules with TEST_OBJECT_2
466 result = smack_accesses_new(&rules);
467 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
469 result = smack_accesses_add(rules,TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
470 RUNNER_ASSERT_MSG(result == 0, "Unable to modify accesses instance");
471 result = smack_accesses_clear(rules);
472 RUNNER_ASSERT_MSG(result == 0, "Clearing rules didn't work.");
474 smack_accesses_free(rules);
476 RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
477 " Clear didn't work. Accesses exist.");
478 RUNNER_ASSERT_MSG(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
479 " Clear didn't work. Accesses exist.");
483 RUNNER_TEST(smack01_storing_and_restoring_rules)
486 * author: Pawel Polawski
487 * test: smack_accesses_new, smack_accesses_add, smack_accesses_add_modify, smack_accesses_add_from_file,
488 * smack_accesses_free, smack_accesses_save
489 * description: This test case will create structure holding SMACK rules and add new one to it. Next rules will be
490 * stored and restored from file.
491 * expect: Rules created and stored in file should be identical to predefined template.
494 struct smack_accesses *rules = NULL; //rules prepared in this test case
495 struct smack_accesses *import_test = NULL; //rules imported from file
497 int result; //result of each operation to be tested by RUNNER_ASSERT
498 int fd, tmp, sample; //file descripptors for save / restore rules tests
500 //int smack_accesses_new(struct smack_accesses **accesses);
501 result = smack_accesses_new(&rules); //rules struct init
502 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
503 result = smack_accesses_new(&import_test); //rules struct init
504 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
507 fd = open("/tmp/smack01_rules", O_RDWR | O_CREAT | O_TRUNC, 0644); //for export prepared rules
508 RUNNER_ASSERT_MSG(fd >= 0, "Unable to create /tmp/smack01_rules");
509 tmp = open("/tmp/smack01_tmp", O_RDWR | O_CREAT | O_TRUNC, 0644); //for import rules exported before
510 RUNNER_ASSERT_MSG(fd >= 0, "Unable to create /tmp/smack01_tmp");
511 sample = open("/etc/smack/test_smack_rules", O_RDONLY, 0644); //reference preinstalled rules
512 RUNNER_ASSERT_MSG(sample >= 0, "Unable to open /etc/smack/test_smack_rules");
514 //int smack_accesses_add(struct smack_accesses *handle, const char *subject,
515 // const char *object, const char *access_type);
516 result = smack_accesses_add(rules, "writer", "book", "rw");
517 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
518 result = smack_accesses_add(rules, "reader", "book", "wx");
519 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
521 //int smack_accesses_add_modify(struct smack_accesses *handle, const char *subject,
522 // const char *object, const char *access_add, const char *access_del);
523 result = smack_accesses_add_modify(rules, "reader", "book", "r", "wx");
524 RUNNER_ASSERT_MSG(0 == result, "Unable to modify smack rules");
526 //int smack_accesses_save(struct smack_accesses *handle, int fd);
527 result = smack_accesses_save(rules, fd);
528 RUNNER_ASSERT_MSG(0 == result, "Unable to save smack_accesses instance in file");
530 //int smack_accesses_add_from_file(struct smack_accesses *accesses, int fd);
531 result = lseek(fd, 0, SEEK_SET);
532 RUNNER_ASSERT_MSG(result == 0, "lseek() error");
533 result = smack_accesses_add_from_file(import_test, fd);
534 RUNNER_ASSERT_MSG(result == 0, "Unable to import rules from file");
536 result = smack_accesses_save(import_test, tmp);
537 RUNNER_ASSERT_MSG(result == 0, "Unable to save smack_accesses instance in file");
539 result = files_compare(fd, tmp); //comparing rules saved in file, restored from it and stored one more time
540 RUNNER_ASSERT_MSG(result == 0, "No match in stored and restored rules");
542 result = files_compare(tmp, sample); //comparing rules stored in file with reference preinstalled rules
543 RUNNER_ASSERT_MSG(result == 0, "No match in stored rules and pattern file");
545 //void smack_accesses_free(struct smack_accesses *handle);
546 smack_accesses_free(rules);
547 smack_accesses_free(import_test);
549 //closing file descriptors
555 RUNNER_TEST_SMACK(smack02_aplying_rules_into_kernel)
558 * author: Pawel Polawski
559 * test: smack_accesses_apply, smack_have_access, smack_revoke_subject, smack_accesses_clear, smack_accesses_new,
560 * smack_accesses_add, smack_accesses_free
561 * description: In this test case aplying rules to kernel will be tested. After that function for test
562 * accesses will be used.
563 * expect: In case of correct rules access should be granted.
566 //CAP_MAC_ADMIN needed for process to be able to change rules in kernel (apllying, removing)
568 struct smack_accesses *rules = NULL; //rules prepared in this test case
569 int result; //for storing functions results
571 result = smack_accesses_new(&rules); //rules struct init
572 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
574 //adding test rules to struct
575 result = smack_accesses_add(rules, "writer", "book", "rwx");
576 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
577 result = smack_accesses_add(rules, "reader", "book", "r");
578 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
579 result = smack_accesses_add(rules, "spy", "book", "rwx");
580 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
582 //int smack_accesses_apply(struct smack_accesses *handle);
583 result = smack_accesses_apply(rules); //applying rules to kernel
584 RUNNER_ASSERT_MSG(result == 0, "Unable to apply rules into kernel");
586 //int smack_have_access(const char *subject, const char *object,
587 // const char *access_type);
588 result = smack_have_access("spy", "book", "rwx"); //should have access - rule exist
589 RUNNER_ASSERT_MSG(result == 1, "Error while checking Smack access");
590 result = smack_have_access("reader", "book", "rwx"); //should have no access - wrong rule, should be "r" only
591 RUNNER_ASSERT_MSG(result == 0, "Error while checking Smack access");
592 result = smack_have_access("mars", "book", "rwx"); //should fail - rule not exist
593 RUNNER_ASSERT_MSG(result == -1, "Error while checking Smack access");
595 //int smack_revoke_subject(const char *subject);
596 result = smack_revoke_subject("snickers"); //this subject do not exist in kernel rules
597 RUNNER_ASSERT_MSG(result == 0, "Error in removing not existing subject from kernel");
598 result = smack_revoke_subject("spy"); //this subject exist in kernel rules
599 RUNNER_ASSERT_MSG(result == 0, "Error in removing existing subject from kernel");
601 result = smack_have_access("spy", "book", "rwx"); //testing access after revoke_subject() from kernel
602 RUNNER_ASSERT_MSG(result == 0, "Error in acces aplied to kernel"); //now spy should have no access
604 result = smack_accesses_add(rules, "twix", "book", "rwx"); //for create new rule as a consequence of use accesses_clear() below
605 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
607 //int smack_accesses_clear(struct smack_accesses *handle);
608 result = smack_accesses_clear(rules); //"spy" removed before by using smack_revoke_subject()
609 RUNNER_ASSERT_MSG(result == 0, "Error in clearing rules in kernel");
611 result = smack_have_access("writer", "book", "rwx"); //testing acces after acces_clear()
612 RUNNER_ASSERT_MSG(result == 0, "Error in acces aplied to kernel"); //now writer also should have no access
615 smack_accesses_free(rules);
618 //pairs of rules for test with mixed cases, different length and mixed order
619 const char *rules_tab[] = {
620 "reader1", "-", "-----",
621 "reader2", "--------", "-----",
622 "reader3", "RwXaT", "rwxat",
623 "reader4", "RrrXXXXTTT", "r-x-t",
624 "reader5", "-r-w-a-t", "rw-at",
625 "reader6", "", "-----",
626 "reader7", "xa--Rt---W", "rwxat",
627 "reader8", "#Ax[T].!~W@1}", "-wxat"
630 RUNNER_TEST_SMACK(smack03_mixed_rule_string_add)
633 * author: Pawel Polawski
634 * test: smack_have_access, smack_accesses_new, smack_accesses_add, smack_accesses_apply, smack_accesses_free
635 * description: In thist test case rules based on mixed string are added to kernel.
636 * Strings are presented above and contains lower / upper case alpha, numbers and special signs.
637 * expect: Rules should be parsed correct and aplied to kernel.
640 //In thist test case mixed string are used as rules applied to kernel, next they are
641 //readed and compared with correct form of rules
643 struct smack_accesses *rules = NULL; //rules prepared in this test case
644 int result; //for storing functions results
648 result = smack_accesses_new(&rules); //rules struct init
649 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
651 //adding test rules with mixed string
652 for (i = 0; i < (3 * 8); i += 3) {
653 result = smack_accesses_add(rules, rules_tab[i], "book", rules_tab[i + 1]); //using mixed rules from table
654 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
658 //FIXME: Using clear() here can cover error in accesses_apply() function
659 //result = smack_accesses_clear(rules);
660 //RUNNER_ASSERT_MSG(result == 0, "Error in clearing rules in kernel");
662 //applying rules to kernel
663 result = smack_accesses_apply(rules);
664 RUNNER_ASSERT_MSG(result == 0, "Unable to apply rules into kernel");
666 //checking accesses using normal rules
667 for (i = 0; i < (3 * 8); i += 3) {
668 if (!strcmp(rules_tab[i + 2], "-----"))
672 result = smack_have_access(rules_tab[i], "book", rules_tab[i + 2]); //using normal rules from table
673 RUNNER_ASSERT_MSG(result == expected, "Error while checking Smack access");
677 smack_accesses_free(rules);
680 RUNNER_TEST_SMACK(smack04_mixed_rule_string_have_access)
683 * author: Pawel Polawski
684 * test: smack_have_access
685 * description: In this test case we testing aplied before SMACK rules and comparing them using mixed strings.
686 * expect: Subjects should have accesses to the objects.
689 //In this test case we checking previous aplied rules but for compare mixed strings are used
695 //rules were added in previous RUNNER_TEST section
696 //checking accesses using mixed rules
697 for (i = 0; i < (3 * 8); i += 3) {
698 if (!strcmp(rules_tab[i + 2], "-----"))
702 result = smack_have_access(rules_tab[i], "book", rules_tab[i + 1]); //using mixed rules from table
703 RUNNER_ASSERT_MSG(result == expected, "Error while checking Smack access");
707 //RUNNER_TEST(smackXX_accesses_add_modify)
710 // - what if we want to apply rule that is already in kernel?
711 // - tests for smack_accesses_add_modify() + smack_have_access() (check if add_modify sets the proper rule)
712 // - smack_accesses_add_modify("subject", "object", "rwx", "rwx") should create empty rule
715 RUNNER_TEST_SMACK(smack05_self_label)
718 * author: Pawel Polawski
719 * test: smack_set_label_for_self, smack_new_label_from_self
720 * description: In this test case process test it own default label. Next label is changed
721 * and tested one more time if change was successfull.
722 * expect: Proces should have default "-" label and can change it to the oter one.
725 //In this test case process will manipulate it own label
731 const int B_SIZE = 8;
734 const char *def_rule = "_";
736 //int smack_new_label_from_self(char **label);
737 result = smack_new_label_from_self(&label);
738 RUNNER_ASSERT_MSG(result >= 0, "Error in getting self label");
740 //comparing this label with default one "_"
741 result = strcmp(label, def_rule);
742 RUNNER_ASSERT_MSG(result == 0, "Wrong default process label");
744 //comparing this rule with received from /proc/self/attr/current
745 fd = open("/proc/self/attr/current", O_RDONLY, 0644);
746 RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /proc/self/attr/current");
747 result = read(fd, buff, B_SIZE);
748 RUNNER_ASSERT_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
749 result = strncmp(buff, def_rule, result);
750 RUNNER_ASSERT_MSG(result == 0, "Wrong default process rule");
754 //now time for setting labels:
756 //int smack_set_label_for_self(const char *label);
757 result = smack_set_label_for_self("cola");
758 RUNNER_ASSERT_MSG(result == 0, "Error in setting self label");
760 //checking new label using smack function
761 result = smack_new_label_from_self(&label);
762 RUNNER_ASSERT_MSG(result >= 0, "Error in getting self label");
763 result = strcmp(label, "cola");
764 RUNNER_ASSERT_MSG(result == 0, "Wrong process label");
766 //checking new label using /proc/self/attr/current
767 result = lseek(fd, 0, SEEK_SET); //going to the file beginning
768 RUNNER_ASSERT_MSG(result == 0, "lseek() error");
769 result = read(fd, buff, B_SIZE);
770 RUNNER_ASSERT_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
771 result = strncmp(buff, "cola", result);
772 RUNNER_ASSERT_MSG(result == 0, "Proces rule in /proc/self/attr/current other than set");
778 //RUNNER_TEST(smackXX_parent_child_label)
780 //In this test case parent process and child labels will be tested
781 //Parent will fork and check child's label. First fork will be with default "_" parent label,
782 //second one witch changed label.
785 //bellow function is from libsmack.c witch changed name
786 const char *xattr(enum smack_label_type type)
789 case SMACK_LABEL_ACCESS:
790 return "security.SMACK64";
791 case SMACK_LABEL_EXEC:
792 return "security.SMACK64EXEC";
793 case SMACK_LABEL_MMAP:
794 return "security.SMACK64MMAP";
795 case SMACK_LABEL_TRANSMUTE:
796 return "security.SMACK64TRANSMUTE";
797 case SMACK_LABEL_IPIN:
798 return "security.SMACK64IPIN";
799 case SMACK_LABEL_IPOUT:
800 return "security.SMACK64IPOUT";
802 /* Should not reach this point */
807 //TODO: In bellow RUNNER_TEST add lget / lset functions to be testet the same way as normal get / set
808 RUNNER_TEST(smack06_get_set_label)
811 * author: Pawel Polawski
812 * test: smack_getlabel, smack_setlabel
813 * description: In this test case file label is tested using SMACK API functions and system xattr functions.
814 * Functions tested here is used for normal files.
815 * expect: Function should return default label, and the new one after change it.
818 //In this test case will be tested setting and getting file label
819 //If file is symbolic link functions should follow it
821 //SMACK xattr from libsmack.c:
823 //case SMACK_LABEL_ACCESS:
824 // return "security.SMACK64";
825 //case SMACK_LABEL_EXEC:
826 // return "security.SMACK64EXEC";
827 //case SMACK_LABEL_MMAP:
828 // return "security.SMACK64MMAP";
829 //case SMACK_LABEL_TRANSMUTE:
830 // return "security.SMACK64TRANSMUTE";
831 //case SMACK_LABEL_IPIN:
832 // return "security.SMACK64IPIN";
833 //case SMACK_LABEL_IPOUT:
834 // return "security.SMACK64IPOUT";
839 const int B_SIZE = 8;
842 const char *file_path = "/etc/smack/test_smack_rules";
845 //preparing environment by restoring default "_" label
846 result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
847 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
850 //int smack_getlabel(const char *path, char** label,
851 // enum smack_label_type type);
852 result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
853 RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
854 //get label, should be default "_"
855 result = strcmp(label, "_");
856 RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
858 //get label using xattr function
859 result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
860 RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
861 //check label, should match the one readed by smack function
862 result = strncmp(buff, "_", result);
863 RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
866 //int smack_setlabel(const char *path, const char* label,
867 // enum smack_label_type type);
868 result = smack_setlabel(file_path, "fanta", SMACK_LABEL_ACCESS);
869 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
872 //get label using smack function
873 result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
874 RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
875 //get label, should be default "fanta"
876 result = strcmp(label, "fanta");
877 RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
879 //get label using xattr function
880 result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
881 RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
882 //check label, should match the one readed by smack function
883 result = strncmp(buff, "fanta", result);
884 RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
887 //RUNNER_TEST(smackXX_get_label_exec)
889 //In this test case EXEC label will be tested
890 //by setting this type of label, reading it and testing executed binary exit status
893 RUNNER_TEST(smack07_l_get_set_label)
896 * author: Pawel Polawski
897 * test: smack_lgetlabel, smack_lsetlabel, smack_getlabel
898 * description: Functions tested here are similar to one from previous test case. The difference
899 * is that in case of symbolic link they follows it and operates on file pointed by it.
900 * expect: All label manipulations should affect file pointed by symbolic link.
906 const int B_SIZE = 8;
909 const char *file_path = "/etc/smack/test_smack_rules_lnk";
912 //preparing environment by restoring default "_" label
913 result = smack_lsetlabel(file_path, "_", SMACK_LABEL_ACCESS);
914 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
915 result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
916 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
919 //int smack_lgetlabel(const char *path, char** label,
920 // enum smack_label_type type);
921 result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
922 RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
923 //get label of symbolic link, should be default "_"
924 result = strcmp(label, "_");
925 RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
927 //get label using xattr function
928 result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
929 RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
930 //check label, should match the one readed by smack function
931 result = strncmp(buff, "_", result);
932 RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
935 //int smack_lsetlabel(const char *path, const char* label,
936 // enum smack_label_type type);
937 result = smack_lsetlabel(file_path, "7up", SMACK_LABEL_ACCESS);
938 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
939 //and set label for file pointed by link
940 result = smack_setlabel(file_path, "mirinda", SMACK_LABEL_ACCESS);
941 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
944 //get label using smack function
945 result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
946 RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
947 //check label, should be "7up"
948 result = strcmp(label, "7up");
949 RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
951 //get label using xattr function
952 result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
953 RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
954 //check label, should match the one readed by smack function
955 result = strncmp(buff, "7up", result);
956 RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
959 //now similar to above, but folowing symbolic link set before to "mirinda"
960 result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
961 RUNNER_ASSERT_MSG(result == 0, "Error gettin label of file pointed by symbolic link");
962 //now label should be "mirinda" for file instead of "7up" set for link
963 result = strcmp(label, "mirinda");
964 RUNNER_ASSERT_MSG(result == 0, "Wrong label of file pointed by symbolic link");
966 //get label using xattr function
967 result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
968 RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
969 //check label, should match the one readed by smack function
970 result = strncmp(buff, "mirinda", result);
971 RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
974 RUNNER_TEST(smack08_f_get_set_label)
977 * author: Pawel Polawski
978 * test: smack_fgetlabel, smack_fsetlabel
979 * description: This test case is similar to test case smack06 above. The difference
980 * is that argument is file descriptor instead of file path.
981 * Function not follow symbolic link and operates directly on it.
982 * expect: All label manipulations should affect symbolic link itself.
988 const int B_SIZE = 8;
992 const char *file_path = "/etc/smack/test_smack_rules";
994 fd = open(file_path, O_RDWR, 0644); //reference preinstalled rules
995 RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules");
997 //preparing environment by restoring default "_" label
998 result = smack_fsetlabel(fd, "_", SMACK_LABEL_ACCESS);
999 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
1002 //int smack_fgetlabel(int fd, char** label,
1003 // enum smack_label_type type);
1004 result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
1005 RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
1006 //check label, should be "_"
1007 result = strcmp(label, "_");
1008 RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
1010 //get label using xattr function
1011 result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
1012 RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
1013 //check label, should match the one readed by smack function
1014 result = strncmp(buff, "_", result);
1015 RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
1018 //int smack_fsetlabel(int fd, const char* label,
1019 // enum smack_label_type type);
1020 result = smack_fsetlabel(fd, "sprite", SMACK_LABEL_ACCESS);
1021 RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
1024 //get label using smack function
1025 result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
1026 RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
1027 //check label, should be "sprite"
1028 result = strcmp(label, "sprite");
1029 RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
1031 //get label using xattr function
1032 result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
1033 RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
1034 //check label, should match the one readed by smack function
1035 result = strncmp(buff, "sprite", result);
1036 RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
1042 RUNNER_TEST_SMACK(smack10_adding_removing_rules)
1047 struct smack_accesses *rulesBasic = NULL;
1049 for (i = 0; i < accessesBasic.size(); ++i)
1052 result = smack_accesses_new(&rulesBasic);
1053 RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1056 result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1057 RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1060 result = smack_accesses_apply(rulesBasic);
1061 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1063 // Checking if accesses were created
1064 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1065 RUNNER_ASSERT_MSG(result == 1,
1066 " Error while checking smack access. Result: " << result);
1068 smack_accesses_free(rulesBasic);
1071 // Deleting all rules
1075 for (i = 0; i < 3; ++i)
1077 // --- Creating rules (r or w or x)
1078 result = smack_accesses_new(&rulesBasic);
1079 RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1082 result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1083 RUNNER_ASSERT_MSG(result == 0, "Unable to add rulesBasic. Result: " << result);
1086 result = smack_accesses_apply(rulesBasic);
1087 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1088 // Checking if accesses were created
1089 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1090 RUNNER_ASSERT_MSG(result == 1,
1091 " Error while checking smack access. Result: " << result);
1093 // Checking if wrong accesses were not created
1094 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1095 RUNNER_ASSERT_MSG(result == 0,
1096 " Error while checking smack access. Result: " << result);
1098 // --- Modifying accesses (r for wx or w for rx or x for rw)
1099 result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,accessesBasic[i + 3].c_str(),accessesBasic[i].c_str());
1100 RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1103 result = smack_accesses_apply(rulesBasic);
1104 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1106 // Checking if accesses were created
1107 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1108 RUNNER_ASSERT_MSG(result == 1,
1109 " Error while checking smack access. Result: " << result);
1111 // Checking if wrong accesses were not created
1112 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1113 RUNNER_ASSERT_MSG(result == 0,
1114 " Error while checking smack access. Result: " << result);
1116 smack_accesses_free(rulesBasic);
1119 // --- Creating complementary rules (r or w or x)
1120 result = smack_accesses_new(&rulesBasic);
1121 RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1124 result = smack_accesses_add(rulesBasic, TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1125 RUNNER_ASSERT_MSG(result == 0, "Unable to add rulesBasic. Result: " << result);
1127 // Checking if accesses were created
1128 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1129 RUNNER_ASSERT_MSG(result == 1,
1130 " Error while checking smack access. Result: " << result);
1133 result = smack_accesses_apply(rulesBasic);
1134 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1136 // Checking if accesses were created
1137 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1138 RUNNER_ASSERT_MSG(result == 1,
1139 " Error while checking smack access. Result: " << result);
1141 // --- Modifying accesses (adding rwx and removing r or w or x)
1142 result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,"rwx",accessesBasic[i].c_str());
1143 RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1146 result = smack_accesses_apply(rulesBasic);
1147 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1149 // Checking if accesses were created
1150 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
1151 RUNNER_ASSERT_MSG(result == 1,
1152 " Error while checking smack access. Result: " << result);
1154 // Checking if wrong accesses were not created
1155 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
1156 RUNNER_ASSERT_MSG(result == 0,
1157 " Error while checking smack access. Result: " << result);
1159 // --- Adding crossing accesses (rx or rw or wx)
1160 result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,accessesBasic[3 + ((i + 1) % 3)].c_str(),"");
1161 RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1164 result = smack_accesses_apply(rulesBasic);
1165 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1167 // Checking if accesses were created
1168 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[3 + ((i + 1) % 3)].c_str());
1169 RUNNER_ASSERT_MSG(result == 1,
1170 " Error while checking smack access. Result: " << result);
1172 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
1173 RUNNER_ASSERT_MSG(result == 1,
1174 " Error while checking smack access. Result: " << result);
1176 // Deleting all rules
1177 result = smack_accesses_add_modify(rulesBasic,TEST_SUBJECT, TEST_OBJECT,"","rwx");
1178 RUNNER_ASSERT_MSG(result == 0, "Unable to add modify rulesBasic. Result: " << result);
1180 result = smack_accesses_apply(rulesBasic);
1181 RUNNER_ASSERT_MSG(result == 0, "Error while checking smack access. Result: " << result);
1183 smack_accesses_free(rulesBasic);
1186 // Deleting all rules
1191 RUNNER_TEST_SMACK(smack11_saving_loading_rules)
1196 struct smack_accesses *rulesBasic = NULL;
1199 removeAccessesAll();
1202 result = smack_accesses_new(&rulesBasic);
1203 RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1205 // Loading file with rwxat rules - test_smack_rules_full
1206 fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1207 RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules_full");
1209 // Adding rules from file
1210 result = smack_accesses_add_from_file(rulesBasic, fd);
1212 RUNNER_ASSERT_MSG(result == 0, "Error importing accesses from file");
1215 result = smack_accesses_apply(rulesBasic);
1216 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1219 result = smack_have_access("test_subject_01", "test_object_01", "rwxat");
1220 RUNNER_ASSERT_MSG(result == 1,
1221 " Error while checking smack accesses.");
1222 result = smack_have_access("test_subject_01", "test_object_02", "rwxat");
1223 RUNNER_ASSERT_MSG(result == 1,
1224 " Error while checking smack accesses.");
1225 result = smack_have_access("test_subject_01", "test_object_03", "rwxat");
1226 RUNNER_ASSERT_MSG(result == 1,
1227 " Error while checking smack accesses.");
1228 result = smack_have_access("test_subject_02", "test_object_01", "rwxat");
1229 RUNNER_ASSERT_MSG(result == 1,
1230 " Error while checking smack accesses.");
1231 result = smack_have_access("test_subject_02", "test_object_02", "rwxat");
1232 RUNNER_ASSERT_MSG(result == 1,
1233 " Error while checking smack accesses.");
1234 result = smack_have_access("test_subject_02", "test_object_03", "rwxat");
1235 RUNNER_ASSERT_MSG(result == 1,
1236 " Error while checking smack accesses.");
1237 result = smack_have_access("test_subject_03", "test_object_01", "rwxat");
1238 RUNNER_ASSERT_MSG(result == 1,
1239 " Error while checking smack accesses.");
1240 result = smack_have_access("test_subject_03", "test_object_02", "rwxat");
1241 RUNNER_ASSERT_MSG(result == 1,
1242 " Error while checking smack accesses.");
1243 result = smack_have_access("test_subject_03", "test_object_03", "rwxat");
1244 RUNNER_ASSERT_MSG(result == 1,
1245 " Error while checking smack accesses.");
1248 removeAccessesAll();
1250 smack_accesses_free(rulesBasic);
1253 result = smack_accesses_new(&rulesBasic);
1254 RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1256 // Loading file with partial wrong rules - test_smack_rules2
1257 fd = open("/etc/smack/test_smack_rules2", O_RDONLY, 0644);
1258 RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules2");
1260 // Adding rules from file
1261 result = smack_accesses_add_from_file(rulesBasic, fd);
1263 RUNNER_ASSERT_MSG(result == 0, "Accesses were loaded from file");
1266 result = smack_accesses_apply(rulesBasic);
1267 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1270 RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_01", "test_object_01"),
1271 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1272 result = smack_have_access("test_subject_01", "test_object_02", "rwat");
1273 RUNNER_ASSERT_MSG(result == 1,
1274 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1275 result = smack_have_access("test_subject_01", "test_object_03", "wat");
1276 RUNNER_ASSERT_MSG(result == 1,
1277 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1278 RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_02", "test_object_01"),
1279 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
1280 result = smack_have_access("test_subject_02", "test_object_02", "wa-ft");
1281 RUNNER_ASSERT_MSG(result == 1,
1282 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1283 result = smack_have_access("test_subject_02", "test_object_03", "wr");
1284 RUNNER_ASSERT_MSG(result == 1,
1285 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1286 result = smack_have_access("test_subject_03", "test_object_01", "a");
1287 RUNNER_ASSERT_MSG(result == 1,
1288 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1289 result = smack_have_access("test_subject_03", "test_object_02", "rwat");
1290 RUNNER_ASSERT_MSG(result == 1,
1291 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1292 result = smack_have_access("test_subject_03", "test_object_03", "w");
1293 RUNNER_ASSERT_MSG(result == 1,
1294 " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
1297 removeAccessesAll();
1299 smack_accesses_free(rulesBasic);
1302 result = smack_accesses_new(&rulesBasic);
1303 RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1305 // Loading file with partial wrong rules - test_smack_rules3
1306 fd = open("/etc/smack/test_smack_rules3", O_RDONLY, 0644);
1307 RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules3");
1309 // Adding rules from file
1310 result = smack_accesses_add_from_file(rulesBasic, fd);
1312 RUNNER_ASSERT_MSG(result != 0, "Accesses were loaded from file");
1315 result = smack_accesses_apply(rulesBasic);
1316 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1319 result = smack_have_access("test_subject_01", "test_object_01", "rwat");
1320 RUNNER_ASSERT_MSG(result == 1,
1321 " Error while checking smack access loaded from /etc/smack/test_smack_rules3. Result: " << result );
1322 RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_01", "test_object_02"),
1323 " Error while checking smack access loaded from /etc/smack/test_smack_rules3. Accesses exist.");
1324 result = smack_have_access("test_subject_01", "test_object_03", "x");
1325 RUNNER_ASSERT_MSG(result == 0,
1326 " Error while checking smack access loaded from /etc/smack/test_smack_rules3. Result: " << result );
1329 removeAccessesAll();
1331 smack_accesses_free(rulesBasic);
1334 result = smack_accesses_new(&rulesBasic);
1335 RUNNER_ASSERT_MSG(result == 0, "Error while creating new accesses. Result: " << result);
1337 // Loading file with partial wrong rules - test_smack_rules4
1338 fd = open("/etc/smack/test_smack_rules4", O_RDONLY, 0644);
1339 RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules4");
1341 // Adding rules from file
1342 result = smack_accesses_add_from_file(rulesBasic, fd);
1344 RUNNER_ASSERT_MSG(result != 0, "Accesses were loaded from file");
1347 result = smack_accesses_apply(rulesBasic);
1348 RUNNER_ASSERT_MSG(result == 0, "Error while applying accesses. Result: " << result);
1351 result = smack_have_access("test_subject_01", "test_object_01", "rxwat");
1352 RUNNER_ASSERT_MSG(result == 1,
1353 " Error while checking smack access loaded from /etc/smack/test_smack_rules4. Result: " << result );
1354 RUNNER_ASSERT_MSG(checkNoAccesses("test_subject_01", "test_object_02"),
1355 " Error while checking smack access loaded from /etc/smack/test_smack_rules4. Accesses exist.");
1356 result = smack_have_access("test_subject_01", "test_object_03", "a");
1357 RUNNER_ASSERT_MSG(result == 0,
1358 " Error while checking smack access loaded from /etc/smack/test_smack_rules4. Result: " << result );
1361 removeAccessesAll();
1363 smack_accesses_free(rulesBasic);
1366 //int smack_new_label_from_socket(int fd, char **label);
1369 static void smack_set_another_label_for_self(void)
1371 static int number = time(NULL);
1376 result = asprintf(&smack_label, "s%d", number);
1377 RUNNER_ASSERT_MSG(result > 0, "asprintf failed");
1378 result = smack_set_label_for_self(smack_label);
1379 RUNNER_ASSERT_MSG(result == 0, "smack_set_label_for_self(" << smack_label << ") failed");
1383 static void smack_unix_sock_server(int sock)
1389 fd = accept(sock, NULL, NULL);
1393 result = smack_new_label_from_self(&smack_label);
1394 RUNNER_ASSERT_MSG(result >= 0, "smack_new_label_from_self() failed");
1395 result = write(fd, smack_label, strlen(smack_label));
1396 RUNNER_ASSERT_MSG(result == (int)strlen(smack_label), "write() failed");
1401 RUNNER_TEST_SMACK(smack09_new_label_from_socket)
1404 struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1406 smack_set_another_label_for_self();
1408 RUNNER_ASSERT_MSG(pid >= 0, "Fork failed");
1409 if (!pid) { /* child process, server */
1413 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1414 RUNNER_ASSERT_MSG(sock >= 0, "socket failed: " << strerror(errno));
1415 result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1416 RUNNER_ASSERT_MSG(result == 0, "bind failed: " << strerror(errno));
1417 result = listen(sock, 1);
1418 RUNNER_ASSERT_MSG(result == 0, "listen failed: " << strerror(errno));
1419 smack_unix_sock_server(sock);
1422 RUNNER_ASSERT_MSG(pid >= 0, "Fork failed");
1423 /* Test if socket label was unaffected by fork() */
1424 smack_unix_sock_server(sock);
1427 smack_set_another_label_for_self();
1428 smack_unix_sock_server(sock);
1432 waitpid(pid, NULL, 0);
1434 } else { /* parent process, client */
1435 sleep(1); /* Give server some time to setup listening socket */
1436 for (int i = 0; i < 4; ++i) {
1438 char smack_label1[SMACK_LABEL_LEN + 1];
1441 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1442 RUNNER_ASSERT_MSG(sock >= 0, "socket failed: " << strerror(errno));
1443 result = connect(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1444 RUNNER_ASSERT_MSG(result == 0, "connect failed: " << strerror(errno));
1446 result = read(sock, smack_label1, SMACK_LABEL_LEN);
1447 RUNNER_ASSERT_MSG(result >= 0, "read failed: " << strerror(errno));
1449 smack_label1[result] = '\0';
1450 result = smack_new_label_from_socket(sock, &smack_label2);
1451 RUNNER_ASSERT_MSG(result >= 0, "smack_label_from_socket failed");
1452 result = strcmp(smack_label1, smack_label2);
1454 RUNNER_ASSERT_MSG(result == 0, "smack labels differ: '" << smack_label1 << "' != '" << smack_label2 << "' i == " << i);
1456 RUNNER_ASSERT_MSG(result != 0, "smack labels do not differ: '" << smack_label1 << "' != '" << smack_label2 << "' i == " << i);
1459 waitpid(pid, NULL, 0);
1463 /////////////////////////////////////////
1464 //////NOSMACK ENVIRONMENT TESTS//////////
1465 /////////////////////////////////////////
1468 * NOSMACK version of smack02 test. Functions, that should return error instead of success:
1469 * - smack_accesses_apply
1470 * - smack_have_access
1471 * - smack_revoke_subject
1472 * - smack_acceesses_clear
1474 * Tests smack03, smack04, smack10, smack_accesses_clear, smack_revoke_subject all use functions
1475 * tested in smack02 test. Results from those functions (smack_have_access, smack_accesses_apply,
1476 * smack_accesses_clear, smack_revoke_subject) would be the same as in this test. Tests mentioned
1477 * above doesn't make much sense on NOSMACK environment when test smack02 exists and passes
1478 * correctly, thus those tests are are not implemented.
1480 RUNNER_TEST_NOSMACK(smack02_aplying_rules_into_kernel_nosmack)
1483 smack_accesses *tmp = NULL;
1487 result = smack_accesses_new(&tmp);
1488 RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
1490 //pass rules to unique_ptr
1491 AccessesUniquePtr rules(tmp, smack_accesses_free);
1493 //adding test rules to struct (same as SMACK version of smack02 test)
1494 result = smack_accesses_add(rules.get(), "writer", "book", "rwx");
1495 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
1496 result = smack_accesses_add(rules.get(), "reader", "book", "r");
1497 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
1498 result = smack_accesses_add(rules.get(), "spy", "book", "rwx");
1499 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
1501 //applying rules to kernel (should fail)
1502 result = smack_accesses_apply(rules.get());
1503 RUNNER_ASSERT_MSG(result == -1, "Unable to apply rules into kernel");
1505 //calls from SMACK version of this test - all should fail because of SMACK being turned off
1506 result = smack_have_access("spy", "book", "rwx");
1507 RUNNER_ASSERT_MSG(result == -1, "smack_have_access should return error (SMACK is off)");
1508 result = smack_have_access("reader", "book", "rwx");
1509 RUNNER_ASSERT_MSG(result == -1, "smack_have_access should return error (SMACK is off)");
1510 result = smack_have_access("mars", "book", "rwx");
1511 RUNNER_ASSERT_MSG(result == -1, "smack_have_access should return error (SMACK is off)");
1513 //testing subject revoking - should return error (no accesses applied = no subjects to revoke)
1514 result = smack_revoke_subject("snickers");
1515 RUNNER_ASSERT_MSG(result == -1, "smack_revoke_subject error - subject doesn't exist.");
1516 result = smack_revoke_subject("spy");
1517 RUNNER_ASSERT_MSG(result == -1, "smack_revoke_subject error - subject doesn't exist.");
1519 //after revoking smack_have_access still should return error
1520 result = smack_have_access("spy", "book", "rwx");
1521 RUNNER_ASSERT_MSG(result == -1, "smack_have_access should return error (SMACK is off).");
1523 result = smack_accesses_add(rules.get(), "twix", "book", "rwx");
1524 RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
1526 //smack_accesses_clear should return error aswell
1527 result = smack_accesses_clear(rules.get());
1528 RUNNER_ASSERT_MSG(result == -1, "Clearing rules should return error - no SMACK on system.");
1530 result = smack_have_access("writer", "book", "rwx");
1531 RUNNER_ASSERT_MSG(result == -1, "smack_have_access should return error (SMACK is off).");
1535 * NOSMACK version of smack11 test. Tests functions:
1536 * - smack_accesses_add_from_file
1538 * Since other SMACK functions were tested in smack02 test, the only function needed to be checked
1539 * is applying rules loaded from file.
1541 RUNNER_TEST_NOSMACK(smack03_saving_loading_rules_nosmack)
1546 smack_accesses* tmp = NULL;
1548 result = smack_accesses_new(&tmp);
1549 RUNNER_ASSERT_MSG(result == 0, "Error during rules creation.");
1551 AccessesUniquePtr rules(tmp, smack_accesses_free);
1553 //open file with rules
1554 fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
1555 RUNNER_ASSERT_MSG(fd >= 0,
1556 "Unable to open /etc/smack/test_smack_rules_full. Errno: " << strerror(errno));
1558 //load accesses from file
1559 result = smack_accesses_add_from_file(rules.get(), fd);
1561 RUNNER_ASSERT_MSG(result == 0, "Error while importing accesses from file. Result: " << result);
1565 * NOSMACK version of smack05 test. Tests if functions getting, or
1566 * setting self label work correctly (that is, return error).
1568 RUNNER_TEST_NOSMACK(smack04_self_label_nosmack)
1574 const int B_SIZE = 8;
1577 //smack_new_label_from_self should fail
1578 result = smack_new_label_from_self(&label);
1579 RUNNER_ASSERT_MSG(result == -1, "new_label_from_self should return error (SMACK is off).");
1580 RUNNER_ASSERT_MSG(label == NULL, "new_label_from_self shouldn't allocate memory to label.");
1582 //We don't need to remember about freeing label - smack_new_label_from_self must return NULL
1583 //label if it's working properly.
1585 // /proc/self/attr/current shouldn't keep any rules inside
1586 fd = open("/proc/self/attr/current", O_RDONLY, 0644); //file exists, so it should open
1587 RUNNER_ASSERT_MSG(fd >= 0, "/proc/self/attr/current failed to open.");
1589 result = read(fd, buff, B_SIZE); //however reading it should return error
1592 RUNNER_ASSERT_MSG(false, "Reading /proc/self/attr/current should return error.");
1595 //setting label for self should fail
1596 result = smack_set_label_for_self("fanta");
1599 RUNNER_ASSERT_MSG(false, "set_label_for_self should return error (SMACK is off).");
1602 //getting previously set label should also fail
1603 result = smack_new_label_from_self(&label);
1606 RUNNER_ASSERT_MSG(false, "new_label_from_self should return error (SMACK is off).");
1610 RUNNER_ASSERT_MSG(false, "new_label_from_self shouldn't allocate memory to label.");
1613 // /proc/self/attr/current still shouldn't keep any rules inside
1614 result = lseek(fd, 0, SEEK_SET); //going to the file beginning
1617 RUNNER_ASSERT_MSG(false, "lseek() error.");
1620 result = read(fd, buff, B_SIZE); //however it should return error
1623 RUNNER_ASSERT_MSG(false, "Reading /proc/self/attr/current should return error.");
1630 * NOSMACK version of smack_accesses_add_modify_x tests.
1632 * Because all smack_accesses_add_modify tests are basically the same (all use smack_accesses_apply
1633 * and smack_have_access, which return -1 when SMACK is turned off), it makes much more sense to
1634 * write one test which will create rules using smack_accesses_add_modify and then check if
1635 * smack_accesses_apply and smack_have_access indeed return -1 when SMACK is turned off.
1637 RUNNER_TEST_NOSMACK(smack05_accesses_add_modify_nosmack)
1640 smack_accesses* tmp = NULL;
1642 result = smack_accesses_new(&tmp);
1643 RUNNER_ASSERT_MSG(result == 0, "Unable to allocate memory for rules. Result: " << result);
1645 AccessesUniquePtr rules(tmp, smack_accesses_free);
1647 //Not doing clean_up() every RUNNER_ASSERT_MSG - what clean_up does is just a creation of new
1648 //rule struct and removal of currenctly added and applied rules. clean_up() must be done only
1649 //after smack_accesses_apply().
1650 result = smack_accesses_add_modify(rules.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1651 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule. Result: " << result);
1653 result = smack_accesses_add_modify(rules.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
1654 RUNNER_ASSERT_MSG(result == 0, "Unable to modify rule. Result: " << result);
1656 result = smack_accesses_apply(rules.get());
1657 RUNNER_ASSERT_MSG(result == -1,
1658 "smack_accesses_apply should return error (SMACK is off). Result: " << result);
1660 result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
1663 RUNNER_ASSERT_MSG(false,
1664 "smack_have_access should return error (SMACK is off). Result: " << result);
1671 * NOSMACK version of smack09 test.
1673 * This test checks if smack_new_label_from_socket reacts correctly. Since label should be
1674 * acquired from getsockopt, and it should fail, we must only set up socket and call
1675 * smack_new_label_from_socket. It should return error.
1677 RUNNER_TEST_NOSMACK(smack09_new_label_from_socket_nosmack)
1680 struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
1685 RUNNER_ASSERT_MSG(pid >= 0, "Fork failed");
1686 if (!pid) { //child (server)
1691 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1692 RUNNER_ASSERT_MSG(sock >= 0, "socket failed: " << strerror(errno));
1694 //Bind it to sockaddr
1695 result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
1698 RUNNER_ASSERT_MSG(false, "bind failed: " << strerror(errno));
1701 //Prepare for listening
1702 result = listen(sock, 1);
1705 RUNNER_ASSERT_MSG(false, "listen failed: " << strerror(errno));
1710 fd = accept(sock, NULL, NULL);
1714 RUNNER_ASSERT_MSG(false, "Failed when accepting connection from client.");
1717 //wait for smack_new_label_from_socket execution
1720 //Close socket and server
1724 else { //parent (client)
1725 //Wait a little bit until server is set up
1730 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1731 RUNNER_ASSERT_MSG(sock >= 0, "socket failed: " << strerror(errno));
1733 //Connect to sockaddr
1734 result = connect(sock, (struct sockaddr*) &sockaddr,
1735 sizeof(struct sockaddr_un));
1738 RUNNER_ASSERT_MSG(false, "connect failed: " << strerror(errno));
1741 //Try getting label, should fail beacuse getsockopt won't get anything
1742 result = smack_new_label_from_socket(sock, &smack_label);
1745 RUNNER_ASSERT_MSG(false, "smack_new_label_from_socket should fail.");
1748 //Close socket, wait for server shutdown
1750 waitpid(pid, NULL, 0);