/*
* @file test_cases.cpp
* @author Pawel Polawski (p.polawski@samsung.com)
+ * @author Jan Olszak (j.olszak@samsung.com)
+ * @author Zofia Abramowska (z.abramowska@samsung.com)
* @version 1.0
- * @brief libprivilege test runer
+ * @brief libsmack test runner
*/
#include <string>
+#include <sstream>
+#include <fcntl.h>
+#include <unistd.h>
#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_multiprocess.h>
#include <dpl/log/log.h>
-
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
-#include <fcntl.h>
-
#include <sys/smack.h>
-
#include <sys/xattr.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/file.h>
+#include <sys/wait.h>
+#include "tests_common.h"
+#include <access_provider.h>
+#include "memory.h"
+
+const char* const TEST_SUBJECT = "test_subject";
+const char* const TEST_OBJECT = "test_object";
+const char* const TEST_OBJECT_2 = "test_object_2";
+
+const std::string testDir = "/opt/home/app/";
+const std::vector<std::string> accessesBasic = { "r", "w", "x", "wx", "rx", "rw", "rwx", "rwxat" };
+
+//This one define is required for sockaddr_un initialization
+#define SOCK_PATH "/tmp/test-smack-socket"
int files_compare(int fd1, int fd2)
{
- int result = 0;
-
//for getting files sizes
struct stat fs1, fs2;
//handlers for mmap()
- void * h1 = MAP_FAILED;
- void * h2 = MAP_FAILED;
+ void *h1 = MAP_FAILED;
+ void *h2 = MAP_FAILED;
//getting files information
- if(fstat(fd1, &fs1) == -1) {
- perror("fstat");
- return -1;
- }
- if(fstat(fd2, &fs2) == -1) {
- perror("fstat");
- return -1;
- }
+ RUNNER_ASSERT_MSG_BT(fstat(fd1, &fs1) == 0, "fstat failed: " << strerror(errno));
+ RUNNER_ASSERT_MSG_BT(fstat(fd2, &fs2) == 0, "fstat failed: " << strerror(errno));
- if(fs1.st_size != fs2.st_size) //if files are identical size will be the same
+ if (fs1.st_size != fs2.st_size) //if files are identical size will be the same
return -1;
//mapping files to process memory
- if((h1 = mmap(0, fs1.st_size, PROT_READ, MAP_SHARED, fd1, 0 )) == MAP_FAILED) {
- result = -1;
- goto end;
- }
- if((h2 = mmap(0, fs2.st_size, PROT_READ, MAP_SHARED, fd2, 0 )) == MAP_FAILED) {
- result = -1;
- goto end;
- }
-
- result = memcmp(h1, h2, fs1.st_size);
+ RUNNER_ASSERT_MSG_BT((h1 = mmap(0, fs1.st_size, PROT_READ, MAP_SHARED, fd1, 0 )) != MAP_FAILED,
+ "mmap failed for fd=" << fd1 << " : " << strerror(errno));
- //cleaning after mmap()
-end:
- if(h2 != MAP_FAILED)
- munmap(h2, fs2.st_size);
- if(h1 != MAP_FAILED)
+ if ((h2 = mmap(0, fs2.st_size, PROT_READ, MAP_SHARED, fd2, 0 )) == MAP_FAILED) {
munmap(h1, fs1.st_size);
+ RUNNER_ASSERT_MSG_BT(h2 != MAP_FAILED, "mmap failed for fd=" << fd2
+ << " : " << strerror(errno));
+ }
+
+ int result = memcmp(h1, h2, fs1.st_size);
+ munmap(h1, fs1.st_size);
+ munmap(h2, fs2.st_size);
return result;
}
RUNNER_TEST_GROUP_INIT(libsmack)
+/**
+ * Helper method to reset privileges at the begginning of tests.
+ */
+void clean_up()
+{
+ smack_revoke_subject(TEST_SUBJECT);
+}
+
+/**
+ * Checking if subject has any access to object
+ */
+bool checkNoAccesses(const char *subject, const char *object)
+{
+ int result;
+ for(const auto &perm : std::vector<std::string> () = {"r", "w", "a","t", "l"}) {
+ result = smack_have_access(subject, object, perm.c_str());
+ if (result == 1) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void removeAccessesAll()
+{
+ for(int i = 1; i <=3; i++)
+ //smack_revoke_subject will fail, when subject does not exist in kernel
+ //as this function is called at test beginning we cannot check return value
+ smack_revoke_subject(("test_subject_0" + std::to_string(i)).c_str());
+}
+
+/**
+ * Add a new access with smack_accesses_add_modify()
+ */
+RUNNER_TEST_SMACK(smack_accesses_add_modify_test_1){
+ int result;
+
+ clean_up();
+
+ struct smack_accesses *rules = NULL;
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ // THE TEST
+ result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"xr","");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify by empty rules");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"xr");
+ RUNNER_ASSERT_MSG_BT(result == 1, "Rule modified (added 'xr'), but no change made.");
+
+ // CLEAN UP
+ clean_up();
+}
+
+
+/**
+ * Test if rules are applied in the right order, and modification works.
+ */
+RUNNER_TEST_SMACK(smack_accesses_add_modify_test_2){
+ int result;
+ struct smack_accesses *rules = NULL;
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ clean_up();
+
+ // THE TEST
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"r","");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+ RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 0,
+ "Modification didn't work");
+
+ // CLEAN UP
+ clean_up();
+}
+
+
+/**
+ * Test if rules are applied in the right order, and modification works.
+ * Using different smack_accesses list to add and delete.
+ */
+RUNNER_TEST_SMACK(smack_accesses_add_modify_test_3){
+ int result;
+ struct smack_accesses *rules = NULL;
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ clean_up();
+
+ // THE TEST
+ // Add r privilage
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"r","");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+ RUNNER_ASSERT_MSG_BT(smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r") == 1,
+ "Adding privileges didn't work");
+
+ // Revoke r privilege
+ rules_ptr.release();
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ rules_ptr.reset(rules);
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Modification didn't work, rule has still 'r' privileges.");
+
+ // CLEAN UP
+ clean_up();
+}
+
+/**
+ * Add a list of privileges and then revoke just ONE of them.
+ */
+RUNNER_TEST_SMACK(smack_accesses_add_modify_test_4){
+ int result;
+ struct smack_accesses *rules = NULL;
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ clean_up();
+
+ // THE TEST
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwxat","");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
+ RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
+ RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
+
+ // CLEAN UP
+ clean_up();
+}
+
+/**
+ * Add a list of privileges and then revoke just ONE of them.
+ * Without applying privileges in between those actions.
+ */
+RUNNER_TEST_SMACK(smack_accesses_add_modify_test_5){
+ int result;
+ struct smack_accesses *rules = NULL;
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ clean_up();
+
+ // THE TEST
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwxat","");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"","r");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"awxt");
+ RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'awxt' privileges.");
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
+ RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
+
+ // CLEAN UP
+ clean_up();
+}
+
+
+/**
+ * Add a list of privileges and then revoke just TWO of them.
+ */
+RUNNER_TEST_SMACK(smack_accesses_add_modify_test_6){
+ int result;
+ struct smack_accesses *rules = NULL;
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ clean_up();
+
+ // THE TEST
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwt","");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"ax","rt");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule.");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"wax");
+ RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule should have 'wax' privileges.");
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,"r");
+ RUNNER_ASSERT_MSG_BT(result != 1, "Modification didn't work. Rule should NOT have 'r' privilege.");
+
+ // CLEAN UP
+ clean_up();
+}
+
+/**
+ * Run smack_accesses_add_modify with the same accesses_add and accesses_del.
+ */
+RUNNER_TEST_SMACK(smack_accesses_add_modify_test_7){
+ unsigned int i;
+ int result;
+
+ struct smack_accesses *rules = NULL;
+
+ for (i = 0; i < accessesBasic.size(); ++i) {
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[i].c_str(), accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
+ " Error while checking smack access. Accesses exist.");
+
+ // CLEAN UP
+ clean_up();
+ }
+}
+
+/**
+ * Revoke subject with previously added rules and revoke it again.
+ */
+RUNNER_TEST_SMACK(smack_revoke_subject_test_1){
+ unsigned int i;
+ int result;
+
+ struct smack_accesses *rules = NULL;
+
+ for (i = 0; i < accessesBasic.size(); ++i) {
+ // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[i].c_str(),"");
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT_2,
+ accessesBasic[i].c_str(),"");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. "
+ "Rule " << accessesBasic[i].c_str() << " does not exist.");
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. "
+ "Rule " << accessesBasic[i].c_str() << " does not exist.");
+
+ // Revoking subject
+ result = smack_revoke_subject(TEST_SUBJECT);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Revoking subject didn't work.");
+
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
+ " Revoke didn't work. Accesses exist.");
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
+ " Revoke didn't work. Accesses exist.");
+
+
+ // Revoking subject again
+ result = smack_revoke_subject(TEST_SUBJECT);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Revoking subject didn't work.");
+
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
+ " Revoke didn't work. Accesses exist.");
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
+ " Revoke didn't work. Accesses exist.");
+
+ }
+}
+
+/**
+ * Clearing accesses
+ */
+RUNNER_TEST_SMACK(smack_accesses_clear_test_1){
+ unsigned int i;
+ int result;
+
+ struct smack_accesses *rules = NULL;
+
+ for (i = 0; i < accessesBasic.size(); ++i) {
+ // Creating and adding rules with TEST_OBJECT and TEST_OBJECT_2
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+ result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
+ result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT_2,
+ accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
+ RUNNER_ASSERT_MSG_BT(smack_accesses_apply(rules_ptr.get()) == 0, "Unable to apply rules");
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule "
+ << accessesBasic[i].c_str() << " does not exist.");
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1, "Modification didn't work. Rule "
+ << accessesBasic[i].c_str() << " does not exist.");
+
+ // Creating and clearing rules with TEST_OBJECT
+ rules_ptr.release();
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ rules_ptr.reset(rules);
+ result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
+ result = smack_accesses_clear(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work.");
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work. Rule "
+ << accessesBasic[i].c_str() << " does exist.");
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT_2,accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1, "Clearing rules didn't work. Rule "
+ << accessesBasic[i].c_str() << " does not exist.");
+
+ // Creating and clearing rules with TEST_OBJECT
+ rules_ptr.release();
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ rules_ptr.reset(rules);
+
+ result = smack_accesses_add(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT_2,
+ accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify accesses instance");
+ result = smack_accesses_clear(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Clearing rules didn't work.");
+
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT),
+ " Clear didn't work. Accesses exist.");
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses(TEST_SUBJECT, TEST_OBJECT_2),
+ " Clear didn't work. Accesses exist.");
+ }
+}
RUNNER_TEST(smack01_storing_and_restoring_rules)
{
/*
* author: Pawel Polawski
- * test: smack_accesses_new, smack_accesses_add, smack_accesses_add_modify, smack_accesses_add_from_file,
+ * test: smack_accesses_new, smack_accesses_add, smack_accesses_add_modify, smack_accesses_add_from_file,
* smack_accesses_free, smack_accesses_save
* description: This test case will create structure holding SMACK rules and add new one to it. Next rules will be
* stored and restored from file.
* expect: Rules created and stored in file should be identical to predefined template.
*/
- struct smack_accesses * rules = NULL; //rules prepared in this test case
- struct smack_accesses * import_test = NULL; //rules imported from file
+ struct smack_accesses *rules = NULL; //rules prepared in this test case
+ struct smack_accesses *import_test = NULL; //rules imported from file
int result; //result of each operation to be tested by RUNNER_ASSERT
int fd, tmp, sample; //file descripptors for save / restore rules tests
//int smack_accesses_new(struct smack_accesses **accesses);
- result = smack_accesses_new(&rules); //rules struct init
- RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
- result = smack_accesses_new(&import_test); //rules struct init
- RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+ RUNNER_ASSERT_BT(smack_accesses_new(&import_test) == 0);
+ SmackAccessesPtr import_ptr(import_test);
//opening files
fd = open("/tmp/smack01_rules", O_RDWR | O_CREAT | O_TRUNC, 0644); //for export prepared rules
- RUNNER_ASSERT_MSG(fd >= 0, "Unable to create /tmp/smack01_rules");
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to create /tmp/smack01_rules");
+ FdUniquePtr fd_ptr(&fd);
tmp = open("/tmp/smack01_tmp", O_RDWR | O_CREAT | O_TRUNC, 0644); //for import rules exported before
- RUNNER_ASSERT_MSG(fd >= 0, "Unable to create /tmp/smack01_tmp");
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to create /tmp/smack01_tmp");
+ FdUniquePtr tmp_ptr(&tmp);
sample = open("/etc/smack/test_smack_rules", O_RDONLY, 0644); //reference preinstalled rules
- RUNNER_ASSERT_MSG(sample >= 0, "Unable to open /etc/smack/test_smack_rules");
+ RUNNER_ASSERT_MSG_BT(sample >= 0, "Unable to open /etc/smack/test_smack_rules");
+ FdUniquePtr sample_ptr(&sample);
- //int smack_accesses_add(struct smack_accesses *handle, const char *subject,
- // const char *object, const char *access_type);
- result = smack_accesses_add(rules, "writer", "book", "rw");
- RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
- result = smack_accesses_add(rules, "reader", "book", "wx");
- RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
+ result = smack_accesses_add(rules_ptr.get(), "writer", "book", "rw");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+ result = smack_accesses_add(rules_ptr.get(), "reader", "book", "wx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
- //int smack_accesses_add_modify(struct smack_accesses *handle, const char *subject,
- // const char *object, const char *access_add, const char *access_del);
- result = smack_accesses_add_modify(rules, "reader", "book", "r", "wx");
- RUNNER_ASSERT_MSG(0 == result, "Unable to modify smack rules");
+ result = smack_accesses_add_modify(rules_ptr.get(), "reader", "book", "r", "wx");
+ RUNNER_ASSERT_MSG_BT(0 == result, "Unable to modify smack rules");
- //int smack_accesses_save(struct smack_accesses *handle, int fd);
- result = smack_accesses_save(rules, fd);
- RUNNER_ASSERT_MSG(0 == result, "Unable to save smack_accesses instance in file");
+ result = smack_accesses_save(rules_ptr.get(), fd);
+ RUNNER_ASSERT_MSG_BT(0 == result, "Unable to save smack_accesses instance in file");
- //int smack_accesses_add_from_file(struct smack_accesses *accesses, int fd);
result = lseek(fd, 0, SEEK_SET);
- RUNNER_ASSERT_MSG(result == 0, "lseek() error");
- result = smack_accesses_add_from_file(import_test, fd);
- RUNNER_ASSERT_MSG(result == 0, "Unable to import rules from file");
-
- result = smack_accesses_save(import_test, tmp);
- RUNNER_ASSERT_MSG(result == 0, "Unable to save smack_accesses instance in file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error");
+ result = smack_accesses_add_from_file(import_ptr.get(), fd);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to import rules from file");
- result = files_compare(fd, tmp); //comparing rules saved in file, restored from it and stored one more time
- RUNNER_ASSERT_MSG(result == 0, "No match in stored and restored rules");
+ result = smack_accesses_save(import_ptr.get(), tmp);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to save smack_accesses instance in file");
- result = files_compare(tmp, sample); //comparing rules stored in file with reference preinstalled rules
- RUNNER_ASSERT_MSG(result == 0, "No match in stored rules and pattern file");
+ //comparing rules saved in file, restored from it and stored one more time
+ result = files_compare(fd, tmp);
+ RUNNER_ASSERT_MSG_BT(result == 0, "No match in stored and restored rules");
- //void smack_accesses_free(struct smack_accesses *handle);
- smack_accesses_free(rules);
- smack_accesses_free(import_test);
-
- //closing file descriptors
- close(fd);
- close(tmp);
- close(sample);
+ //comparing rules stored in file with reference preinstalled rules
+ result = files_compare(tmp, sample);
+ RUNNER_ASSERT_MSG_BT(result == 0, "No match in stored rules and pattern file");
}
-RUNNER_TEST(smack02_aplying_rules_into_kernel)
+RUNNER_TEST_SMACK(smack02_aplying_rules_into_kernel)
{
/*
* author: Pawel Polawski
//CAP_MAC_ADMIN needed for process to be able to change rules in kernel (apllying, removing)
- struct smack_accesses * rules = NULL; //rules prepared in this test case
+ struct smack_accesses *rules = NULL; //rules prepared in this test case
int result; //for storing functions results
- result = smack_accesses_new(&rules); //rules struct init
- RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
//adding test rules to struct
- result = smack_accesses_add(rules, "writer", "book", "rwx");
- RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
- result = smack_accesses_add(rules, "reader", "book", "r");
- RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
- result = smack_accesses_add(rules, "spy", "book", "rwx");
- RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
-
- //int smack_accesses_apply(struct smack_accesses *handle);
- result = smack_accesses_apply(rules); //applying rules to kernel
- RUNNER_ASSERT_MSG(result == 0, "Unable to apply rules into kernel");
-
- //int smack_have_access(const char *subject, const char *object,
- // const char *access_type);
- result = smack_have_access("spy", "book", "rwx"); //should have access - rule exist
- RUNNER_ASSERT_MSG(result == 1, "Error while checking Smack access");
- result = smack_have_access("reader", "book", "rwx"); //should have no access - wrong rule, should be "r" only
- RUNNER_ASSERT_MSG(result == 0, "Error while checking Smack access");
- result = smack_have_access("mars", "book", "rwx"); //should have no acces - rule not exist
- RUNNER_ASSERT_MSG(result == 0, "Error while checking Smack access");
-
- //int smack_revoke_subject(const char *subject);
- result = smack_revoke_subject("snickers"); //this subject do not exist in kernel rules
- RUNNER_ASSERT_MSG(result == -1, "Error in rmoving not existing subject from kernel"); // <----- TODO: this one should be changed (== 0) after fixing revoke_subject in kernel
+ result = smack_accesses_add(rules_ptr.get(), "writer", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+ result = smack_accesses_add(rules_ptr.get(), "reader", "book", "r");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+ result = smack_accesses_add(rules_ptr.get(), "spy", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+
+ result = smack_accesses_apply(rules_ptr.get()); //applying rules to kernel
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to apply rules into kernel");
+
+ //should have access - rule exist
+ result = smack_have_access("spy", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 1, "Error while checking Smack access");
+ //should have no access - wrong rule, should be "r" only
+ result = smack_have_access("reader", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while checking Smack access");
+ //should fail - rule not exist
+ result = smack_have_access("s02badsubjectlabel", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == -1, "Error while checking Smack access");
+
+ //this subject do not exist in kernel rules
+ result = smack_revoke_subject("s02nonexistinglabel");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in removing not existing subject from kernel");
result = smack_revoke_subject("spy"); //this subject exist in kernel rules
- RUNNER_ASSERT_MSG(result == 0, "Error in rmoving existing subject from kernel");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in removing existing subject from kernel");
- result = smack_have_access("spy", "book", "rwx"); //testing access after revoke_subject() from kernel
- RUNNER_ASSERT_MSG(result == 0, "Error in acces aplied to kernel"); //now spy should have no access
- result = smack_have_access("spy", "book", "-----"); //and should have "-----" rule
- RUNNER_ASSERT_MSG(result == 1, "Error in acces aplied to kernel");
+ //testing access after revoke_subject() from kernel
+ result = smack_have_access("spy", "book", "rwx");
+ //now spy should have no access
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in acces aplied to kernel");
- result = smack_accesses_add(rules, "twix", "book", "rwx"); //for create new rule as a consequence of use accesses_clear() below
- RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
+ //for create new rule as a consequence of use accesses_clear() below
+ result = smack_accesses_add(rules_ptr.get(), "s02subjectlabel", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
- //int smack_accesses_clear(struct smack_accesses *handle);
- result = smack_accesses_clear(rules); //"spy" removed before by using smack_revoke_subject()
- RUNNER_ASSERT_MSG(result == 0, "Error in clearing rules in kernel");
+ //"spy" removed before by using smack_revoke_subject()
+ result = smack_accesses_clear(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in clearing rules in kernel");
- result = smack_have_access("writer", "book", "rwx"); //testing acces after acces_clear()
- RUNNER_ASSERT_MSG(result == 0, "Error in acces aplied to kernel"); //now writer also should have no access
- result = smack_have_access("writer", "book", "-----"); //and should have "-----" rule
- RUNNER_ASSERT_MSG(result == 1, "Error in acces aplied to kernel");
- result = smack_have_access("twix", "book", "-----"); //rule created by calling accesses_clear()
- RUNNER_ASSERT_MSG(result == 1, "Error in acces aplied to kernel");
+ //testing acces after acces_clear()
+ result = smack_have_access("writer", "book", "rwx");
+ //now writer also should have no access
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in acces aplied to kernel");
- //free resources
- smack_accesses_free(rules);
}
//pairs of rules for test with mixed cases, different length and mixed order
-char * rules_tab[] = {
- "reader1", "-", "-----",
- "reader2", "--------", "-----",
- "reader3", "RwXaT", "rwxat",
- "reader4", "RrrXXXXTTT", "r-x-t",
- "reader5", "-r-w-a-t", "rw-at",
- "reader6", "", "-----",
- "reader7", "xa--Rt---W", "rwxat",
- "reader8", "#Ax[T].!~W@1}", "-wxat"
- };
-
-RUNNER_TEST(smack03_mixed_rule_string_add)
+std::vector< std::vector<std::string> > correct_rules = {
+ { "reader1", "-", "------" },
+ { "reader2", "--------", "------" },
+ { "reader3", "RwXaTl", "rwxatl" },
+ { "reader4", "RrrXXXXTTT", "r-x-t-" },
+ { "reader5", "-r-w-a-t-", "rw-at-" },
+ { "reader6", "", "------" },
+ { "reader7", "xa--Rt---W--L", "rwxatl" },
+};
+
+RUNNER_TEST_SMACK(smack03_mixed_rule_string_add)
{
/*
* author: Pawel Polawski
//In thist test case mixed string are used as rules applied to kernel, next they are
//readed and compared with correct form of rules
- struct smack_accesses * rules = NULL; //rules prepared in this test case
+ struct smack_accesses *rules = NULL; //rules prepared in this test case
int result; //for storing functions results
- int i;
+ int expected;
- result = smack_accesses_new(&rules); //rules struct init
- RUNNER_ASSERT_MSG(result == 0, "Unable to create smack_accesses instance");
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
//adding test rules with mixed string
- for(i = 0; i < (3 * 8) ; i += 3) {
- result = smack_accesses_add(rules, rules_tab[i], "book", rules_tab[i + 1]); //using mixed rules from table
- RUNNER_ASSERT_MSG(result == 0, "Unable to add smack rules");
+ for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
+ //using mixed rules from table
+ result = smack_accesses_add(rules_ptr.get(),
+ (*rule)[0].c_str(),
+ "book",
+ (*rule)[1].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
}
//clearing
//FIXME: Using clear() here can cover error in accesses_apply() function
//result = smack_accesses_clear(rules);
- //RUNNER_ASSERT_MSG(result == 0, "Error in clearing rules in kernel");
+ //RUNNER_ASSERT_MSG_BT(result == 0, "Error in clearing rules in kernel");
//applying rules to kernel
- result = smack_accesses_apply(rules);
- RUNNER_ASSERT_MSG(result == 0, "Unable to apply rules into kernel");
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to apply rules into kernel");
//checking accesses using normal rules
- for(i = 0; i < (3 * 8) ; i += 3) {
- result = smack_have_access(rules_tab[i], "book", rules_tab[i + 2]); //using normal rules from table
- RUNNER_ASSERT_MSG(result == 1, "Error while checking Smack access");
+ for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
+ if ((*rule)[2] == "------")
+ expected = 0;
+ else
+ expected = 1;
+ //using normal rules from table
+ result = smack_have_access((*rule)[0].c_str(),
+ "book",
+ (*rule)[2].c_str());
+ RUNNER_ASSERT_MSG_BT(result == expected, "Error while checking Smack access");
}
-
- //free resources
- smack_accesses_free(rules);
-
}
-RUNNER_TEST(smack04_mixed_rule_string_have_access)
+RUNNER_TEST_SMACK(smack04_mixed_rule_string_have_access)
{
/*
* author: Pawel Polawski
//In this test case we checking previous aplied rules but for compare mixed strings are used
int result;
- int i;
+ int expected;
//rules were added in previous RUNNER_TEST section
//checking accesses using mixed rules
- for(i = 0; i < (3 * 8) ; i += 3) {
- result = smack_have_access(rules_tab[i], "book", rules_tab[i + 1]); //using mixed rules from table
- RUNNER_ASSERT_MSG(result == 1, "Error while checking Smack access");
+ for (auto rule=correct_rules.begin(); rule != correct_rules.end(); ++rule) {
+ if ((*rule)[2] == "------")
+ expected = 0;
+ else
+ expected = 1;
+ //using mixed rules from table
+ result = smack_have_access((*rule)[0].c_str(),
+ "book",
+ (*rule)[1].c_str());
+ RUNNER_ASSERT_MSG_BT(result == expected, "Error while checking Smack access");
}
}
// - smack_accesses_add_modify("subject", "object", "rwx", "rwx") should create empty rule
//}
-RUNNER_TEST(smack05_self_label)
+RUNNER_TEST_SMACK(smack05_self_label)
{
/*
* author: Pawel Polawski
//In this test case process will manipulate it own label
- char * label = NULL;
+ char *label = NULL;
int result;
int fd;
const int B_SIZE = 8;
char buff[B_SIZE];
- char * def_rule = "_";
+ const char *def_rule = "_";
- //int smack_new_label_from_self(char **label);
result = smack_new_label_from_self(&label);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting self label");
-
+ RUNNER_ASSERT_MSG_BT(result >= 0, "Error in getting self label");
//comparing this label with default one "_"
result = strcmp(label, def_rule);
- RUNNER_ASSERT_MSG(result == 0, "Wrong default process label");
+ free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong default process label");
//comparing this rule with received from /proc/self/attr/current
fd = open("/proc/self/attr/current", O_RDONLY, 0644);
- RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /proc/self/attr/current");
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /proc/self/attr/current");
+ FdUniquePtr fd_ptr(&fd);
result = read(fd, buff, B_SIZE);
- RUNNER_ASSERT_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
+ RUNNER_ASSERT_MSG_BT(result >= 0, "Error in reading from file /proc/self/attr/current");
result = strncmp(buff, def_rule, result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong default process rule");
-
- free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong default process rule");
//now time for setting labels:
- //int smack_set_label_for_self(const char *label);
result = smack_set_label_for_self("cola");
- RUNNER_ASSERT_MSG(result == 0, "Error in setting self label");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting self label");
//checking new label using smack function
result = smack_new_label_from_self(&label);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting self label");
+ RUNNER_ASSERT_MSG_BT(result >= 0, "Error in getting self label");
result = strcmp(label, "cola");
- RUNNER_ASSERT_MSG(result == 0, "Wrong process label");
+ free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong process label");
//checking new label using /proc/self/attr/current
result = lseek(fd, 0, SEEK_SET); //going to the file beginning
- RUNNER_ASSERT_MSG(result == 0, "lseek() error");
+ RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error");
result = read(fd, buff, B_SIZE);
- RUNNER_ASSERT_MSG(result >= 0, "Error in reading from file /proc/self/attr/current");
+ RUNNER_ASSERT_MSG_BT(result >= 0, "Error in reading from file /proc/self/attr/current");
result = strncmp(buff, "cola", result);
- RUNNER_ASSERT_MSG(result == 0, "Proces rule in /proc/self/attr/current other than set");
-
- free(label);
- close(fd);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Proces rule in /proc/self/attr/current other than set");
}
//RUNNER_TEST(smackXX_parent_child_label)
//{
- //In this test case parent process and child labels will be tested
- //Parent will fork and check child's label. First fork will be with default "_" parent label,
- //second one witch changed label.
+//In this test case parent process and child labels will be tested
+//Parent will fork and check child's label. First fork will be with default "_" parent label,
+//second one witch changed label.
//}
//bellow function is from libsmack.c witch changed name
-char * xattr(enum smack_label_type type)
+const char *xattr(enum smack_label_type type)
{
switch (type) {
case SMACK_LABEL_ACCESS:
case SMACK_LABEL_IPOUT:
return "security.SMACK64IPOUT";
default:
- /* Should not reach this point */
- return NULL;
+ /* Should not reach this point */
+ return NULL;
}
}
// return "security.SMACK64IPOUT";
int result;
- char * label = NULL;
-
- const int B_SIZE = 8;
- char buff[B_SIZE];
-
- char * file_path = "/etc/smack/test_smack_rules";
+ char *label = NULL;
+ char buff[SMACK_LABEL_LEN+1];
+ const char* s06testlabel = "s06testlabel";
+ const char *file_path = "/etc/smack/test_smack_rules";
//preparing environment by restoring default "_" label
result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
-
- //int smack_getlabel(const char *path, char** label,
- // enum smack_label_type type);
result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
//get label, should be default "_"
result = strcmp(label, "_");
- RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
+
//get label using xattr function
- result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
- RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
+ result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
+ RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
//check label, should match the one readed by smack function
result = strncmp(buff, "_", result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
-
-
- //int smack_setlabel(const char *path, const char* label,
- // enum smack_label_type type);
- result = smack_setlabel(file_path, "fanta", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
+ result = smack_setlabel(file_path, s06testlabel, SMACK_LABEL_ACCESS);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
//get label using smack function
result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
- //get label, should be default "fanta"
- result = strcmp(label, "fanta");
- RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
+ //get label, should be default s06testlabel
+ result = strcmp(label, s06testlabel);
free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
+
//get label using xattr function
- result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
- RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
+ result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
+ RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
//check label, should match the one readed by smack function
- result = strncmp(buff, "fanta", result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
+ result = strncmp(buff, s06testlabel, result);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
}
//RUNNER_TEST(smackXX_get_label_exec)
//{
- //In this test case EXEC label will be tested
- //by setting this type of label, reading it and testing executed binary exit status
+//In this test case EXEC label will be tested
+//by setting this type of label, reading it and testing executed binary exit status
//}
RUNNER_TEST(smack07_l_get_set_label)
*/
int result;
- char * label = NULL;
+ char *label = NULL;
- const int B_SIZE = 8;
- char buff[B_SIZE];
-
- char * file_path = "/etc/smack/test_smack_rules_lnk";
+ char buff[SMACK_LABEL_LEN+1];
+ const char* s07testlabel1 = "s07testlabel1";
+ const char* s07testlabel2 = "s07testlabel2";
+ const char *file_path = "/etc/smack/test_smack_rules_lnk";
//preparing environment by restoring default "_" label
result = smack_lsetlabel(file_path, "_", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
result = smack_setlabel(file_path, "_", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
-
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
- //int smack_lgetlabel(const char *path, char** label,
- // enum smack_label_type type);
result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
//get label of symbolic link, should be default "_"
result = strcmp(label, "_");
- RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
+
//get label using xattr function
- result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
- RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
+ result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
+ RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
//check label, should match the one readed by smack function
result = strncmp(buff, "_", result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
-
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
- //int smack_lsetlabel(const char *path, const char* label,
- // enum smack_label_type type);
- result = smack_lsetlabel(file_path, "7up", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
+ result = smack_lsetlabel(file_path, s07testlabel1, SMACK_LABEL_ACCESS);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
//and set label for file pointed by link
- result = smack_setlabel(file_path, "mirinda", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
-
+ result = smack_setlabel(file_path, s07testlabel2, SMACK_LABEL_ACCESS);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
//get label using smack function
result = smack_lgetlabel(file_path, &label, SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
- //check label, should be "7up"
- result = strcmp(label, "7up");
- RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
+ //check label, should be s07testlabel1
+ result = strcmp(label, s07testlabel1);
free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
+
//get label using xattr function
- result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
- RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
+ result = lgetxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
+ RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
//check label, should match the one readed by smack function
- result = strncmp(buff, "7up", result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
+ result = strncmp(buff, s07testlabel1, result);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
-
- //now similar to above, but folowing symbolic link set before to "mirinda"
+ //now similar to above, but folowing symbolic link set before to s07testlabel2
result = smack_getlabel(file_path, &label, SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error gettin label of file pointed by symbolic link");
- //now label should be "mirinda" for file instead of "7up" set for link
- result = strcmp(label, "mirinda");
- RUNNER_ASSERT_MSG(result == 0, "Wrong label of file pointed by symbolic link");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error gettin label of file pointed by symbolic link");
+ //now label should be s07testlabel2 for file instead of s07testlabel1 set for link
+ result = strcmp(label, s07testlabel2);
free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong label of file pointed by symbolic link");
+
//get label using xattr function
- result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
- RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
+ result = getxattr(file_path, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
+ RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
//check label, should match the one readed by smack function
- result = strncmp(buff, "mirinda", result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
+ result = strncmp(buff, s07testlabel2, result);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
}
RUNNER_TEST(smack08_f_get_set_label)
*/
int result;
- char * label = NULL;
+ char *label = NULL;
- const int B_SIZE = 8;
- char buff[B_SIZE];
+ char buff[SMACK_LABEL_LEN+1];
+ const char* s08testlabel = "s08testlabel";
int fd;
- char * file_path = "/etc/smack/test_smack_rules";
+ const char *file_path = "/etc/smack/test_smack_rules";
fd = open(file_path, O_RDWR, 0644); //reference preinstalled rules
- RUNNER_ASSERT_MSG(fd >= 0, "Unable to open /etc/smack/test_smack_rules");
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules");
+ FdUniquePtr fd_ptr(&fd);
//preparing environment by restoring default "_" label
result = smack_fsetlabel(fd, "_", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
-
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
- //int smack_fgetlabel(int fd, char** label,
- // enum smack_label_type type);
result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
//check label, should be "_"
result = strcmp(label, "_");
- RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
+
//get label using xattr function
- result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
- RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
+ result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
+ RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
//check label, should match the one readed by smack function
result = strncmp(buff, "_", result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong file default label");
-
-
- //int smack_fsetlabel(int fd, const char* label,
- // enum smack_label_type type);
- result = smack_fsetlabel(fd, "sprite", SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in setting ACCESS label for file");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file default label");
+ result = smack_fsetlabel(fd, s08testlabel, SMACK_LABEL_ACCESS);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in setting ACCESS label for file");
//get label using smack function
result = smack_fgetlabel(fd, &label, SMACK_LABEL_ACCESS);
- RUNNER_ASSERT_MSG(result == 0, "Error in getting smack ACCESS label from file");
- //check label, should be "sprite"
- result = strcmp(label, "sprite");
- RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error in getting smack ACCESS label from file");
+ //check label, should be s08testlabel
+ result = strcmp(label, s08testlabel);
free(label);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
+
//get label using xattr function
- result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, B_SIZE);
- RUNNER_ASSERT_MSG(result > 0, "Error in getting xattr from file");
+ result = fgetxattr(fd, xattr(SMACK_LABEL_ACCESS), buff, SMACK_LABEL_LEN);
+ RUNNER_ASSERT_MSG_BT(result > 0, "Error in getting xattr from file");
//check label, should match the one readed by smack function
- result = strncmp(buff, "sprite", result);
- RUNNER_ASSERT_MSG(result == 0, "Wrong file label");
+ result = strncmp(buff, s08testlabel, result);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Wrong file label");
+}
+
+RUNNER_TEST_SMACK(smack10_adding_removing_rules)
+{
+ unsigned int i;
+ int result;
+
+ struct smack_accesses *rules = NULL;
+
+ for (i = 0; i < accessesBasic.size(); ++i)
+ {
+ // Creating rules
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ // Adding accesses
+ result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+
+ // Checking if accesses were created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ // Deleting all rules
+ clean_up();
+ }
+
+ for (i = 0; i < 3; ++i)
+ {
+ // --- Creating rules (r or w or x)
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ // Adding accesses
+ result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add rulesBasic. Result: " << result);
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+ // Checking if accesses were created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ // Checking if wrong accesses were not created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0,
+ " Error while checking smack access. Result: " << result);
+
+ // --- Modifying accesses (r for wx or w for rx or x for rw)
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[i + 3].c_str(),accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+
+ // Checking if accesses were created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ // Checking if wrong accesses were not created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0,
+ " Error while checking smack access. Result: " << result);
+
+ rules_ptr.release();
+ // --- Creating complementary rules (r or w or x)
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ rules_ptr.reset(rules);
+
+ // Adding accesses
+ result = smack_accesses_add(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add rulesBasic. Result: " << result);
+
+ // Checking if accesses were created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+
+ // Checking if accesses were created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ // --- Modifying accesses (adding rwx and removing r or w or x)
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,"rwx",
+ accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+
+ // Checking if accesses were created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i + 3].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ // Checking if wrong accesses were not created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, accessesBasic[i].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0,
+ " Error while checking smack access. Result: " << result);
+
+ // --- Adding crossing accesses (rx or rw or wx)
+ result = smack_accesses_add_modify(rules_ptr.get(),TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[3 + ((i + 1) % 3)].c_str(),"");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+
+ // Checking if accesses were created
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT,
+ accessesBasic[3 + ((i + 1) % 3)].c_str());
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access. Result: " << result);
+
+ // Deleting all rules
+ result = smack_accesses_add_modify(rules,TEST_SUBJECT, TEST_OBJECT,"","rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add modify rulesBasic. Result: " << result);
+
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while checking smack access. Result: " << result);
+
+ // Deleting all rules
+ clean_up();
+ }
+}
+
+RUNNER_TEST_SMACK(smack11_saving_loading_rules)
+{
+ int result;
+ int fd;
+ struct smack_accesses *rules = NULL;
+ // Pre-cleanup
+ removeAccessesAll();
+
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ SmackAccessesPtr rules_ptr(rules);
+
+ // Loading file with rwxat rules - test_smack_rules_full
+ fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules_full");
+
+ // Adding rules from file
+ result = smack_accesses_add_from_file(rules_ptr.get(), fd);
+ close(fd);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error importing accesses from file");
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+
+ // Checking rules
+ result = smack_have_access("test_subject_01", "test_object_02", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+ result = smack_have_access("test_subject_01", "test_object_03", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+ result = smack_have_access("test_subject_02", "test_object_01", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+ result = smack_have_access("test_subject_02", "test_object_02", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+ result = smack_have_access("test_subject_02", "test_object_03", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+ result = smack_have_access("test_subject_03", "test_object_01", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+ result = smack_have_access("test_subject_03", "test_object_02", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+ result = smack_have_access("test_subject_03", "test_object_03", "rwxat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack accesses.");
+
+ // Removing rules
+ removeAccessesAll();
+
+ // Creating rules
+ rules_ptr.release();
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ rules_ptr.reset(rules);
+
+ // Loading file with partial wrong rules - test_smack_rules2
+ fd = open("/etc/smack/test_smack_rules2", O_RDONLY, 0644);
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules2");
+
+ // Adding rules from file
+ result = smack_accesses_add_from_file(rules_ptr.get(), fd);
+ close(fd);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error importing accesses from file");
+
+ // Applying rules
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while applying accesses. Result: " << result);
+
+ // Checking rules
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses("test_subject_01", "test_object_01"),
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
+ result = smack_have_access("test_subject_01", "test_object_02", "rwatl");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
+ result = smack_have_access("test_subject_01", "test_object_03", "wat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
+ RUNNER_ASSERT_MSG_BT(checkNoAccesses("test_subject_02", "test_object_01"),
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Accesses exist.");
+ result = smack_have_access("test_subject_02", "test_object_02", "wa-lt");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
+ result = smack_have_access("test_subject_02", "test_object_03", "wr");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
+ result = smack_have_access("test_subject_03", "test_object_01", "a");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
+ result = smack_have_access("test_subject_03", "test_object_02", "rwat");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
+ result = smack_have_access("test_subject_03", "test_object_03", "w---l-");
+ RUNNER_ASSERT_MSG_BT(result == 1,
+ " Error while checking smack access loaded from /etc/smack/test_smack_rules2. Result: " << result );
+
+ // Removing rules
+ removeAccessesAll();
+
+ // Creating rules
+ rules_ptr.release();
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ rules_ptr.reset(rules);
+
+ // Loading file with partial wrong rules - test_smack_rules3
+ fd = open("/etc/smack/test_smack_rules3", O_RDONLY, 0644);
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules3");
+
+ // Adding rules from file
+ result = smack_accesses_add_from_file(rules_ptr.get(), fd);
+ close(fd);
+ RUNNER_ASSERT_MSG_BT(result != 0, "Accesses were loaded from file");
+
+ // Removing rules
+ removeAccessesAll();
+
+ // Creating rules
+ rules_ptr.release();
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ rules_ptr.reset(rules);
+
+ // Loading file with partial wrong rules - test_smack_rules4
+ fd = open("/etc/smack/test_smack_rules4", O_RDONLY, 0644);
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Unable to open /etc/smack/test_smack_rules4");
+
+ // Adding rules from file
+ result = smack_accesses_add_from_file(rules_ptr.get(), fd);
close(fd);
+ RUNNER_ASSERT_MSG_BT(result != 0, "Accesses were loaded from file");
+
+ // Removing rules
+ removeAccessesAll();
}
//int smack_new_label_from_socket(int fd, char **label);
+
+static void smack_set_another_label_for_self(void)
+{
+ static int number = time(NULL);
+
+ number++;
+ std::string smack_label("s" + std::to_string(number));
+
+ int result = smack_set_label_for_self(smack_label.c_str());
+ RUNNER_ASSERT_MSG_BT(result == 0, "smack_set_label_for_self(" << smack_label << ") failed");
+}
+
+static void smack_unix_sock_server(int sock)
+{
+ int fd, result;
+ char *label;
+
+ alarm(2);
+ fd = accept(sock, NULL, NULL);
+ alarm(0);
+ RUNNER_ASSERT_BT(fd >= 0);
+ FdUniquePtr fd_ptr(&fd);
+
+ result = smack_new_label_from_self(&label);
+ RUNNER_ASSERT_MSG_BT(result >= 0, "smack_new_label_from_self() failed");
+ CStringPtr label_ptr(label);
+ result = write(fd, label, strlen(label));
+ RUNNER_ASSERT_MSG_BT(result == (int)strlen(label), "write() failed");
+
+}
+
+RUNNER_MULTIPROCESS_TEST_SMACK(smack09_new_label_from_socket)
+{
+ int pid;
+ struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
+ unlink(SOCK_PATH);
+ smack_set_another_label_for_self();
+ pid = fork();
+ RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
+ if (!pid) { /* child process, server */
+ int sock, result;
+
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
+ SockUniquePtr sock_ptr(&sock);
+ result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
+ RUNNER_ASSERT_MSG_BT(result == 0, "bind failed: " << strerror(errno));
+ result = listen(sock, 1);
+ RUNNER_ASSERT_MSG_BT(result == 0, "listen failed: " << strerror(errno));
+ smack_unix_sock_server(sock);
+
+ pid = fork();
+ RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
+ /* Test if socket label was unaffected by fork() */
+ smack_unix_sock_server(sock);
+ if (!pid) {
+ usleep (100);
+ smack_set_another_label_for_self();
+ smack_unix_sock_server(sock);
+ }
+
+ exit(0);
+ } else { /* parent process, client */
+ sleep(1); /* Give server some time to setup listening socket */
+ for (int i = 0; i < 4; ++i) {
+ int sock, result;
+ char smack_label1[SMACK_LABEL_LEN + 1];
+ char *smack_label2;
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
+ SockUniquePtr sock_ptr(&sock);
+ result = connect(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
+ RUNNER_ASSERT_MSG_BT(result == 0, "connect failed: " << strerror(errno));
+ alarm(2);
+ result = read(sock, smack_label1, SMACK_LABEL_LEN);
+ alarm(0);
+ RUNNER_ASSERT_MSG_BT(result >= 0, "read failed: " << strerror(errno));
+ smack_label1[result] = '\0';
+ result = smack_new_label_from_socket(sock, &smack_label2);
+ SmackLabelPtr label2_ptr(smack_label2);
+ RUNNER_ASSERT_MSG_BT(result >= 0, "smack_label_from_socket failed");
+ result = strcmp(smack_label1, label2_ptr.get());
+ if (i < 3)
+ RUNNER_ASSERT_MSG_BT(result == 0, "smack labels differ: '" << smack_label1
+ << "' != '" << smack_label2 << "' i == " << i);
+ else
+ RUNNER_ASSERT_MSG_BT(result != 0, "smack labels do not differ: '" << smack_label1
+ << "' != '" << smack_label2 << "' i == " << i);
+ }
+ }
+}
+
+void createFileWithLabel(const std::string &filePath, const std::string &fileLabel)
+{
+ //create temporary file and set label for it
+ mode_t systemMask;
+
+ unlink(filePath.c_str());
+ //allow to create file with 777 rights
+ systemMask = umask(0000);
+ int fd = open(filePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+ //restore system mask
+ umask(systemMask);
+ RUNNER_ASSERT_MSG_BT(fd > -1, "Unable to create file for tests: " << strerror(errno));
+
+ //for descriptor protection
+ FdUniquePtr fd_ptr(&fd);
+
+ //change owner and group to user APP
+ int ret = chown(filePath.c_str(), APP_UID, APP_GID);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to change file owner: " << strerror(errno));
+
+ //set smack label on file
+ ret = smack_setlabel(filePath.c_str(), fileLabel.c_str(), SMACK_LABEL_ACCESS);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to set label for file: " << ret);
+
+ char *label = NULL;
+ ret = smack_getlabel(filePath.c_str(), &label, SMACK_LABEL_ACCESS);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Unable to get label from file");
+ std::string label_str(label ? label : "");
+ free(label);
+ RUNNER_ASSERT_MSG_BT(label_str == fileLabel, "File label not match set label");
+}
+
+void prepareEnvironment(const std::string &subject, const std::string &object, const std::string &access)
+{
+ const std::string ruleAll = "x";
+
+ SecurityServer::AccessProvider provider(subject);
+ provider.addObjectRule("User", ruleAll);
+ provider.addObjectRule(object, access);
+ provider.applyAndSwithToUser(APP_UID, APP_GID);
+}
+
+//- Add "l" rule to system
+//
+//Should be able to add "l" rule to system
+RUNNER_CHILD_TEST_SMACK(smack13_0_checking_laccess_mode_enabled_on_device)
+{
+ std::string selfLabel = "smack13_0";
+ std::string filename = "smack13_0_file";
+
+ //function inside checks if rule exist after add it
+ SecurityServer::AccessProvider provider(selfLabel);
+ provider.addObjectRule(filename, "l");
+ provider.apply();
+
+ int ret = smack_have_access(selfLabel.c_str(), filename.c_str(), "l");
+ RUNNER_ASSERT_MSG_BT(ret == 1, "Error in adding laccess rule - l");
+}
+
+//- Create file
+//- Set label for file and self
+//- Drop privileges
+//
+//Should have no access due to missing SMACK rule
+RUNNER_CHILD_TEST_SMACK(smack13_1_checking_laccess_mode)
+{
+ std::string selfLabel = "smack13_1";
+ std::string filename = "smack13_1_file";
+ std::string filePath = testDir + filename;
+
+ createFileWithLabel(filePath, filename);
+ int fd = open(filePath.c_str(), O_RDWR, 0);
+ FdUniquePtr fd_ptr(&fd);
+
+ SecurityServer::AccessProvider provider(selfLabel);
+ provider.applyAndSwithToUser(APP_UID, APP_GID);
+
+ int ret = flock(fd, LOCK_EX | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
+ ret = flock(fd, LOCK_UN | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
+ ret = flock(fd, LOCK_SH | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file: " << strerror(errno));
+}
+
+//- Create file
+//- Set label for file and self
+//- Add SMACK rule "l"
+//- Drop privileges
+//
+//Should be able to lock file even without "w" rule
+RUNNER_CHILD_TEST_SMACK(smack13_2_checking_laccess_mode_with_l_rule)
+{
+ std::string selfLabel = "smack13_2";
+ std::string filename = "smack13_2_file";
+ std::string filePath = testDir + filename;
+
+ createFileWithLabel(filePath, filename);
+ int fd = open(filePath.c_str(), O_RDWR, 0);
+ FdUniquePtr fd_ptr(&fd);
+
+ prepareEnvironment(selfLabel, filename, "l");
+
+ int ret = flock(fd, LOCK_EX | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
+ ret = flock(fd, LOCK_UN | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to unlock file: " << strerror(errno));
+ ret = flock(fd, LOCK_SH | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
+}
+
+//- Create file
+//- Set label for file and self
+//- Add SMACK rule "w"
+//- Drop privileges
+//
+//Should be able to lock file even without "l" rule
+RUNNER_CHILD_TEST_SMACK(smack13_3_checking_laccess_mode_with_w_rule)
+{
+ std::string selfLabel = "smack13_3";
+ std::string filename = "smack13_3_file";
+ std::string filePath = testDir + filename;
+
+ createFileWithLabel(filePath, filename);
+ int fd = open(filePath.c_str(), O_RDWR, 0);
+ FdUniquePtr fd_ptr(&fd);
+
+ prepareEnvironment(selfLabel, filename, "w");
+
+ int ret = flock(fd, LOCK_EX | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
+ ret = flock(fd, LOCK_UN | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to unlock file: " << strerror(errno));
+ ret = flock(fd, LOCK_SH | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
+}
+
+//- Create file
+//- Set label for file and self
+//- Add SMACK rule "rw"
+//- Drop privileges
+//- Lock file (shared lock)
+//- Spawn child process
+//- Child tries to lock file (shared)
+//
+//Child should be able to lock file due to shared lock
+RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_0_checking_laccess_mode_w_rule_child)
+{
+ std::string selfLabel = "smack13_4_0";
+ std::string filename = "smack13_4_0_file";
+ std::string filePath = testDir + filename;
+
+ createFileWithLabel(filePath, filename);
+ int fd = open(filePath.c_str(), O_RDWR);
+ FdUniquePtr fd_ptr(&fd);
+ int ret = flock(fd, LOCK_SH | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ //child process
+ prepareEnvironment(selfLabel, filename, "rw");
+
+ int child_fd = open(filePath.c_str(), O_RDWR);
+ RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
+ //for descriptor protection
+ FdUniquePtr child_fd_ptr(&child_fd);
+
+ ret = flock(child_fd, LOCK_SH | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to lock file with shared lock: "
+ << strerror(errno));
+ }
+}
+
+//- Create file
+//- Set label for file and self
+//- Add SMACK rule "l"
+//- Drop privileges
+//- Lock file (shared lock)
+//- Spawn child process
+//- Child tries to lock file (shared)
+//
+//Child should be able to lock file due to shared lock
+RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_1_checking_laccess_mode_l_rule_child)
+{
+ std::string selfLabel = "smack13_4_1";
+ std::string filename = "smack13_4_1_file";
+ std::string filePath = testDir + filename;
+
+ createFileWithLabel(filePath, filename);
+ int fd = open(filePath.c_str(), O_RDWR);
+ FdUniquePtr fd_str(&fd);
+ int ret = flock(fd, LOCK_SH | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to shared lock file: " << strerror(errno));
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ //child process
+ //"r" is only for open in O_RDONLY mode
+ prepareEnvironment(selfLabel, filename, "rl");
+
+ int child_fd = open(filePath.c_str(), O_RDONLY, 0);
+ RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
+ //for descriptor protection
+ FdUniquePtr child_fd_ptr(&child_fd);
+
+ ret = flock(child_fd, LOCK_SH | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to lock file with shared lock: "
+ << strerror(errno));
+ }
+}
+
+//- Create file
+//- Set label for file and self
+//- Add SMACK rule "rw"
+//- Drop privileges
+//- Lock file (exclusive lock)
+//- Spawn child process
+//- Child tries to lock file (exclusive / shared)
+//
+//Child should not be able to lock file due to exclusive lock
+RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_2_checking_laccess_mode_w_rule_child)
+{
+ std::string selfLabel = "smack13_4_2";
+ std::string filename = "smack13_4_2_file";
+ std::string filePath = testDir + filename;
+
+ createFileWithLabel(filePath, filename);
+ int fd = open(filePath.c_str(), O_RDWR);
+ FdUniquePtr fd_ptr(&fd);
+ int ret = flock(fd, LOCK_EX | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ //child process
+ prepareEnvironment(selfLabel, filename, "rw");
+
+ int child_fd = open(filePath.c_str(), O_RDWR, 0);
+ RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
+ //for descriptor protection
+ FdUniquePtr child_fd_ptr(&child_fd);
+
+ ret = flock(child_fd, LOCK_EX | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file with exclusive lock");
+ }
+}
+
+//- Create file
+//- Set label for file and self
+//- Add SMACK rule "l"
+//- Drop privileges
+//- Lock file (exclusive lock)
+//- Spawn child process
+//- Child tries to lock file (exclusive / shared)
+//
+//Child should not be able to lock file due to exclusive lock
+RUNNER_MULTIPROCESS_TEST_SMACK(smack13_4_3_checking_laccess_mode_l_rule_child)
+{
+ std::string selfLabel = "smack13_4_3";
+ std::string filename = "smack13_4_3_file";
+ std::string filePath = testDir + filename;
+
+ createFileWithLabel(filePath, filename);
+ int fd = open(filePath.c_str(), O_RDWR, 0);
+ FdUniquePtr fd_ptr(&fd);
+ int ret = flock(fd, LOCK_EX | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ //child process
+ //"r" is only for open in O_RDONLY mode
+ prepareEnvironment(selfLabel, filename, "rl");
+
+ int child_fd = open(filePath.c_str(), O_RDONLY, 0);
+ RUNNER_ASSERT_MSG_BT(child_fd > -1, "Unable to open created file: " << strerror(errno));
+ //for descriptor protection
+ FdUniquePtr child_fd_ptr(&child_fd);
+
+ ret = flock(child_fd, LOCK_EX | LOCK_NB);
+ RUNNER_ASSERT_MSG_BT(ret < 0, "Error, able to lock file with eclusive lock");
+ }
+}
+
+
+/////////////////////////////////////////
+//////NOSMACK ENVIRONMENT TESTS//////////
+/////////////////////////////////////////
+
+/**
+ * NOSMACK version of smack02 test. Functions, that should return error instead of success:
+ * - smack_accesses_apply
+ * - smack_have_access
+ * - smack_revoke_subject
+ * - smack_acceesses_clear
+ *
+ * Tests smack03, smack04, smack10, smack_accesses_clear, smack_revoke_subject all use functions
+ * tested in smack02 test. Results from those functions (smack_have_access, smack_accesses_apply,
+ * smack_accesses_clear, smack_revoke_subject) would be the same as in this test. Tests mentioned
+ * above doesn't make much sense on NOSMACK environment when test smack02 exists and passes
+ * correctly, thus those tests are are not implemented.
+ */
+RUNNER_TEST_NOSMACK(smack02_aplying_rules_into_kernel_nosmack)
+{
+
+ smack_accesses *rules = NULL;
+ int result;
+
+ //init rules
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+ //pass rules to unique_ptr
+ SmackAccessesPtr rules_ptr(rules);
+
+ //adding test rules to struct (same as SMACK version of smack02 test)
+ result = smack_accesses_add(rules_ptr.get(), "writer", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+ result = smack_accesses_add(rules_ptr.get(), "reader", "book", "r");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+ result = smack_accesses_add(rules_ptr.get(), "spy", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+
+ //applying rules to kernel (should fail)
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == -1, "Unable to apply rules into kernel");
+
+ //calls from SMACK version of this test - all should fail because of SMACK being turned off
+ result = smack_have_access("spy", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
+ result = smack_have_access("reader", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
+ result = smack_have_access("s02badsubjectlabel", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off)");
+
+ //testing subject revoking - should return error (no accesses applied = no subjects to revoke)
+ result = smack_revoke_subject("s02nonexistinglabel");
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_revoke_subject error - subject doesn't exist.");
+ result = smack_revoke_subject("spy");
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_revoke_subject error - subject doesn't exist.");
+
+ //after revoking smack_have_access still should return error
+ result = smack_have_access("spy", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off).");
+
+ result = smack_accesses_add(rules_ptr.get(), "s02subjectlabel", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to add smack rules");
+
+ //smack_accesses_clear should return error aswell
+ result = smack_accesses_clear(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == -1, "Clearing rules should return error - no SMACK on system.");
+
+ result = smack_have_access("writer", "book", "rwx");
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_have_access should return error (SMACK is off).");
+}
+
+/**
+ * NOSMACK version of smack11 test. Tests functions:
+ * - smack_accesses_add_from_file
+ *
+ * Since other SMACK functions were tested in smack02 test, the only function needed to be checked
+ * is applying rules loaded from file.
+ */
+RUNNER_TEST_NOSMACK(smack03_saving_loading_rules_nosmack)
+{
+ int result;
+ int fd;
+
+ smack_accesses* tmp = NULL;
+
+ RUNNER_ASSERT_BT(smack_accesses_new(&tmp) == 0);
+ SmackAccessesPtr rules(tmp);
+
+ //open file with rules
+ fd = open("/etc/smack/test_smack_rules_full", O_RDONLY, 0644);
+ RUNNER_ASSERT_MSG_BT(fd >= 0,
+ "Unable to open /etc/smack/test_smack_rules_full. Errno: " << strerror(errno));
+
+ //load accesses from file
+ result = smack_accesses_add_from_file(rules.get(), fd);
+ close(fd);
+ RUNNER_ASSERT_MSG_BT(result == 0, "Error while importing accesses from file. Result: " << result);
+}
+
+/**
+ * NOSMACK version of smack05 test. Tests if functions getting, or
+ * setting self label work correctly (that is, return error).
+ */
+RUNNER_TEST_NOSMACK(smack04_self_label_nosmack)
+{
+ char* label = NULL;
+ int result;
+ int fd;
+
+ char buff[SMACK_LABEL_LEN+1];
+
+ //smack_new_label_from_self should fail
+ result = smack_new_label_from_self(&label);
+ RUNNER_ASSERT_MSG_BT(result == -1, "new_label_from_self should return error (SMACK is off).");
+ RUNNER_ASSERT_MSG_BT(label == NULL, "new_label_from_self shouldn't allocate memory to label.");
+ //We don't need to remember about freeing label - smack_new_label_from_self must return NULL
+ //label if it's working properly.
+
+ // /proc/self/attr/current shouldn't keep any rules inside
+ fd = open("/proc/self/attr/current", O_RDONLY, 0644); //file exists, so it should open
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "/proc/self/attr/current failed to open.");
+ FdUniquePtr fd_ptr(&fd);
+
+ result = read(fd, buff, SMACK_LABEL_LEN); //however reading it should return error
+ RUNNER_ASSERT_MSG_BT(result < 0, "Reading /proc/self/attr/current should return error.");
+
+ //setting label for self should fail
+ result = smack_set_label_for_self("s04testlabel");
+ RUNNER_ASSERT_MSG_BT(result == -1, "set_label_for_self should return error (SMACK is off).");
+
+ //getting previously set label should also fail
+ result = smack_new_label_from_self(&label);
+ RUNNER_ASSERT_MSG_BT(result == -1, "new_label_from_self should return error (SMACK is off).");
+ RUNNER_ASSERT_MSG_BT(label == NULL, "new_label_from_self shouldn't allocate memory to label.");
+
+ // /proc/self/attr/current still shouldn't keep any rules inside
+ result = lseek(fd, 0, SEEK_SET); //going to the file beginning
+ RUNNER_ASSERT_MSG_BT(result == 0, "lseek() error.");
+
+ result = read(fd, buff, SMACK_LABEL_LEN); //however it should return error
+ RUNNER_ASSERT_MSG_BT(result < 0, "Reading /proc/self/attr/current should return error.");
+}
+
+/**
+ * NOSMACK version of smack_accesses_add_modify_x tests.
+ *
+ * Because all smack_accesses_add_modify tests are basically the same (all use smack_accesses_apply
+ * and smack_have_access, which return -1 when SMACK is turned off), it makes much more sense to
+ * write one test which will create rules using smack_accesses_add_modify and then check if
+ * smack_accesses_apply and smack_have_access indeed return -1 when SMACK is turned off.
+ */
+RUNNER_TEST_NOSMACK(smack05_accesses_add_modify_nosmack)
+{
+ int result;
+ smack_accesses* rules = NULL;
+
+ RUNNER_ASSERT_BT(smack_accesses_new(&rules) == 0);
+
+ SmackAccessesPtr rules_ptr(rules);
+
+ //Not doing clean_up() every RUNNER_ASSERT_MSG - what clean_up does is just a creation of new
+ //rule struct and removal of currenctly added and applied rules. clean_up() must be done only
+ //after smack_accesses_apply().
+ result = smack_accesses_add_modify(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule. Result: " << result);
+
+ result = smack_accesses_add_modify(rules_ptr.get(), TEST_SUBJECT, TEST_OBJECT, "rwx", "");
+ RUNNER_ASSERT_MSG_BT(result == 0, "Unable to modify rule. Result: " << result);
+
+ result = smack_accesses_apply(rules_ptr.get());
+ RUNNER_ASSERT_MSG_BT(result == -1,
+ "smack_accesses_apply should return error (SMACK is off). Result: " << result);
+
+ result = smack_have_access(TEST_SUBJECT, TEST_OBJECT, "rwx");
+ if(result != -1) {
+ clean_up();
+ RUNNER_ASSERT_MSG_BT(false,
+ "smack_have_access should return error (SMACK is off). Result: " << result);
+ }
+
+ clean_up();
+}
+
+/**
+ * NOSMACK version of smack09 test.
+ *
+ * This test checks if smack_new_label_from_socket reacts correctly. Since label should be
+ * acquired from getsockopt, and it should fail, we must only set up socket and call
+ * smack_new_label_from_socket. It should return error.
+ */
+RUNNER_MULTIPROCESS_TEST_NOSMACK(smack09_new_label_from_socket_nosmack)
+{
+ int pid;
+ struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
+ unlink(SOCK_PATH);
+ char* smack_label;
+
+ pid = fork();
+ RUNNER_ASSERT_MSG_BT(pid >= 0, "Fork failed");
+ if (!pid) { //child (server)
+ int sock, result;
+ int fd;
+
+ //Create new socket
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
+ SockUniquePtr sock_ptr(&sock);
+
+ //Bind it to sockaddr
+ result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
+ RUNNER_ASSERT_MSG_BT(result == 0, "bind failed: " << strerror(errno));
+
+ //Prepare for listening
+ result = listen(sock, 1);
+ RUNNER_ASSERT_MSG_BT(result == 0, "listen failed: " << strerror(errno));
+
+ //Accept client
+ alarm(2);
+ fd = accept(sock, NULL, NULL);
+ alarm(0);
+ RUNNER_ASSERT_MSG_BT(fd >= 0, "Failed when accepting connection from client.");
+ FdUniquePtr fd_ptr(&fd);
+
+ //wait for smack_new_label_from_socket execution
+ usleep(200);
+
+ //Close server
+ exit(0);
+ }
+ else { //parent (client)
+ //Wait a little bit until server is set up
+ sleep(1);
+ int sock, result;
+
+ //Create socket
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ SockUniquePtr sock_ptr(&sock);
+ RUNNER_ASSERT_MSG_BT(sock >= 0, "socket failed: " << strerror(errno));
+
+ //Connect to sockaddr
+ result = connect(sock, (struct sockaddr*) &sockaddr,
+ sizeof(struct sockaddr_un));
+ RUNNER_ASSERT_MSG_BT(result == 0, "connect failed: " << strerror(errno));
+
+ //Try getting label, should fail beacuse getsockopt won't get anything
+ result = smack_new_label_from_socket(sock, &smack_label);
+ RUNNER_ASSERT_MSG_BT(result == -1, "smack_new_label_from_socket should fail.");
+ }
+}