Added test cases for SMACK L-access mode
authorPawel Polawski <p.polawski@partner.samsung.com>
Mon, 4 Nov 2013 14:39:50 +0000 (15:39 +0100)
committerMarcin Niesluchowski <m.niesluchow@samsung.com>
Thu, 23 Jan 2014 14:21:36 +0000 (15:21 +0100)
[Issue#]        SSDWSSP-502
[Bug/Feature]   Verify if L-access mode is working on private images
[Cause]         Missing tests for L-access mode
[Solution]      Tests for L-access mode added
[Verification]  Compile, run tests. They are included to smack tests

Change-Id: I54bbc7b2f3bf235091d98c7b4ea87febd546ba97

tests/common/tests_common.cpp
tests/common/tests_common.h
tests/libprivilege-control-tests/test_cases_nosmack.cpp
tests/libsmack-tests/test_cases.cpp

index e2794a6..f8d2d67 100644 (file)
@@ -50,7 +50,7 @@ int smack_check(void)
 #endif
 }
 
-void closeFileDsr(int *fd)
+void closeFdPtr(int *fd)
 {
     close(*fd);
 }
index 7c33277..1722c0b 100644 (file)
@@ -128,7 +128,7 @@ int drop_root_privileges(void);
     void Proc##Multi()
 
 
-void closeFileDsr(int *fd);
+void closeFdPtr(int *fd);
 void setLabelForSelf(const int line, const char *label);
 
 namespace DB {
index 005c7f2..a16149b 100644 (file)
 
 #define APP_SET_PRIV_PATH_REAL "/etc/smack/test_privilege_control_DIR/test_set_app_privilege/test_APP_REAL"
 
-namespace {
-void closefdptr(int* fd) { close(*fd); }
-typedef std::unique_ptr<int, std::function<void (int*)> > FDUniquePtr;
-} //namespace
 
 /////////////////////////////////////////
 //////NOSMACK ENVIRONMENT TESTS//////////
index a3499fd..0a48b28 100644 (file)
 #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>
 
 #define TEST_SUBJECT  "test_subject"
 #define TEST_OBJECT   "test_oject"
@@ -44,6 +47,7 @@
 
 #define SOCK_PATH "/tmp/test-smack-socket"
 
+std::string testDir = "/opt/home/app/";
 std::vector<std::string> accessesBasic = { "r", "w", "x", "wx", "rx", "rw", "rwx", "rwxat" };
 
 int files_compare(int fd1, int fd2)
@@ -1453,6 +1457,296 @@ RUNNER_MULTIPROCESS_TEST_SMACK(smack09_new_label_from_socket)
     }
 }
 
+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(fd > -1, "Unable to create file for tests: " << strerror(errno));
+
+    //for descriptor protection
+    FDUniquePtr fp(&fd, closeFdPtr);
+
+    //change owner and group to user APP
+    int ret = chown(filePath.c_str(), APP_UID, APP_GID);
+    RUNNER_ASSERT_MSG(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(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(ret == 0, "Unable to get label from file");
+    std::string label_str(label ? label : "");
+    free(label);
+    RUNNER_ASSERT_MSG(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.allowAPI("system::homedir", ruleAll, TRACE_FROM_HERE);
+    provider.allowAPI(object, access, TRACE_FROM_HERE);
+    provider.applyAndSwithToUser(APP_UID, APP_GID, TRACE_FROM_HERE);
+}
+
+//- 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.allowAPI(filename, "l", TRACE_FROM_HERE);
+    provider.apply(TRACE_FROM_HERE);
+
+    int ret = smack_have_access(selfLabel.c_str(), filename.c_str(), "l");
+    RUNNER_ASSERT_MSG(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 fp(&fd, closeFdPtr);
+
+    SecurityServer::AccessProvider provider(selfLabel);
+    provider.applyAndSwithToUser(APP_UID, APP_GID, TRACE_FROM_HERE);
+
+    int ret = flock(fd, LOCK_EX | LOCK_NB);
+    RUNNER_ASSERT_MSG(ret < 0, "Error, able to lock file: " << strerror(errno));
+    ret = flock(fd, LOCK_UN | LOCK_NB);
+    RUNNER_ASSERT_MSG(ret < 0, "Error, able to lock file: " << strerror(errno));
+    ret = flock(fd, LOCK_SH | LOCK_NB);
+    RUNNER_ASSERT_MSG(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 fp(&fd, closeFdPtr);
+
+    prepareEnvironment(selfLabel, filename, "l");
+
+    int ret = flock(fd, LOCK_EX | LOCK_NB);
+    RUNNER_ASSERT_MSG(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
+    ret = flock(fd, LOCK_UN | LOCK_NB);
+    RUNNER_ASSERT_MSG(ret == 0, "Error, unable to unlock file: " << strerror(errno));
+    ret = flock(fd, LOCK_SH | LOCK_NB);
+    RUNNER_ASSERT_MSG(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 fp(&fd, closeFdPtr);
+
+    prepareEnvironment(selfLabel, filename, "w");
+
+    int ret = flock(fd, LOCK_EX | LOCK_NB);
+    RUNNER_ASSERT_MSG(ret == 0, "Error, unable to exclusive lock file: " << strerror(errno));
+    ret = flock(fd, LOCK_UN | LOCK_NB);
+    RUNNER_ASSERT_MSG(ret == 0, "Error, unable to unlock file: " << strerror(errno));
+    ret = flock(fd, LOCK_SH | LOCK_NB);
+    RUNNER_ASSERT_MSG(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 fp(&fd, closeFdPtr);
+    int ret = flock(fd, LOCK_SH | LOCK_NB);
+    RUNNER_ASSERT_MSG(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(child_fd > -1, "Unable to open created file: " << strerror(errno));
+
+        //for descriptor protection
+        FDUniquePtr fp(&child_fd, closeFdPtr);
+
+        ret = flock(child_fd, LOCK_SH | LOCK_NB);
+        RUNNER_ASSERT_MSG(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 fp(&fd, closeFdPtr);
+    int ret = flock(fd, LOCK_SH | LOCK_NB);
+    RUNNER_ASSERT_MSG(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(child_fd > -1, "Unable to open created file: " << strerror(errno));
+
+        //for descriptor protection
+        FDUniquePtr fp(&child_fd, closeFdPtr);
+
+        ret = flock(child_fd, LOCK_SH | LOCK_NB);
+        RUNNER_ASSERT_MSG(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 fp(&fd, closeFdPtr);
+    int ret = flock(fd, LOCK_EX | LOCK_NB);
+    RUNNER_ASSERT_MSG(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(child_fd > -1, "Unable to open created file: " << strerror(errno));
+
+        //for descriptor protection
+        FDUniquePtr fp(&child_fd, closeFdPtr);
+
+        ret = flock(child_fd, LOCK_EX | LOCK_NB);
+        RUNNER_ASSERT_MSG(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 fp(&fd, closeFdPtr);
+    int ret = flock(fd, LOCK_EX | LOCK_NB);
+    RUNNER_ASSERT_MSG(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(child_fd > -1, "Unable to open created file: " << strerror(errno));
+
+        //for descriptor protection
+        FDUniquePtr fp(&child_fd, closeFdPtr);
+
+        ret = flock(child_fd, LOCK_EX | LOCK_NB);
+        RUNNER_ASSERT_MSG(ret < 0, "Error, able to lock file with eclusive lock");
+    }
+}
+
+
 /////////////////////////////////////////
 //////NOSMACK ENVIRONMENT TESTS//////////
 /////////////////////////////////////////