#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"
#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)
}
}
+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//////////
/////////////////////////////////////////