#include <fcntl.h>
#include <stdio.h>
#include <memory.h>
-#include <semaphore.h>
#include <unistd.h>
#include <attr/xattr.h>
#include <string>
#include <unordered_set>
+ #include <ftw.h>
#include <grp.h>
#include <pwd.h>
#include <access_provider.h>
#include <dpl/log/log.h>
#include <dpl/test/test_runner.h>
- #include <libprivilege-control_test_common.h>
#include <passwd_access.h>
#include <tests_common.h>
#include <sm_api.h>
return "User::Pkg::" + pkgId;
}
+ #define FTW_MAX_FDS 16
+
+ static int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
+ int /*typeflag*/, struct FTW* /*ftwbuf*/)
+ {
+ smack_lsetlabel(fpath, nullptr, SMACK_LABEL_ACCESS);
+ smack_lsetlabel(fpath, nullptr, SMACK_LABEL_EXEC);
+ smack_lsetlabel(fpath, nullptr, SMACK_LABEL_TRANSMUTE);
+
+ return 0;
+ }
+
+ static int nftw_set_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/,
+ int /*typeflag*/, struct FTW* /*ftwbuf*/)
+ {
+ smack_lsetlabel(fpath, "canary_label", SMACK_LABEL_ACCESS);
+ smack_lsetlabel(fpath, "canary_label", SMACK_LABEL_EXEC);
+ smack_lsetlabel(fpath, nullptr, SMACK_LABEL_TRANSMUTE);
+
+ return 0;
+ }
+
+ static int nftw_check_labels_non_app_dir(const char *fpath, const struct stat* /*sb*/,
+ int /*typeflag*/, struct FTW* /*ftwbuf*/)
+ {
+ int result;
+ CStringPtr labelPtr;
+ char* label = nullptr;
+
+ /* ACCESS */
+ result = smack_lgetlabel(fpath, &label, SMACK_LABEL_ACCESS);
+ labelPtr.reset(label);
+ RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
+ result = strcmp("canary_label", labelPtr.get());
+ RUNNER_ASSERT_MSG(result == 0, "ACCESS label on " << fpath << " is overwritten");
+
+ /* EXEC */
+ result = smack_lgetlabel(fpath, &label, SMACK_LABEL_EXEC);
+ labelPtr.reset(label);
+ RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
+ result = strcmp("canary_label", labelPtr.get());
+ RUNNER_ASSERT_MSG(result == 0, "EXEC label on " << fpath << " is overwritten");
+
+ /* TRANSMUTE */
+ result = smack_lgetlabel(fpath, &label, SMACK_LABEL_TRANSMUTE);
+ labelPtr.reset(label);
+ RUNNER_ASSERT_MSG(result == 0, "Could not get label for the path");
+ RUNNER_ASSERT_MSG(labelPtr.get() == nullptr, "TRANSMUTE label on " << fpath << " is set");
+
+ return 0;
+ }
+
static int nftw_check_sm_labels_app_dir(const char *fpath, const struct stat *sb,
const char* correctLabel, bool transmute_test, bool exec_test)
{
uninstall_app(app_id, pkg_id, true);
install_app(app_id, pkg_id);
- struct sockaddr_un sockaddr = {AF_UNIX, SOCK_PATH};
- //Clean up before creating socket
- unlink(SOCK_PATH);
- int sock = socket(AF_UNIX, SOCK_STREAM, 0);
- RUNNER_ASSERT_ERRNO_MSG(sock >= 0, "socket failed");
+ const auto sockaddr = UDSHelpers::makeAbstractAddress("sm_test_03.socket");
+ int sock = UDSHelpers::createServer(&sockaddr);
SockUniquePtr sockPtr(&sock);
- //Bind socket to address
- result = bind(sock, (struct sockaddr*) &sockaddr, sizeof(struct sockaddr_un));
- RUNNER_ASSERT_ERRNO_MSG(result == 0, "bind failed");
+
//Set socket label to something different than expecedLabel
- result = smack_set_label_for_file(sock, XATTR_NAME_SMACKIPIN, socketLabel);
+ result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPIN, socketLabel);
RUNNER_ASSERT_ERRNO_MSG(result == 0,
"Can't set socket label. Result: " << result);
- result = smack_set_label_for_file(sock, XATTR_NAME_SMACKIPOUT, socketLabel);
+ result = smack_set_label_for_file(*sockPtr, XATTR_NAME_SMACKIPOUT, socketLabel);
RUNNER_ASSERT_ERRNO_MSG(result == 0,
"Can't set socket label. Result: " << result);
Api::setProcessLabel(app_id);
- result = smack_new_label_from_file(sock, XATTR_NAME_SMACKIPIN, &label);
+ result = smack_new_label_from_file(*sockPtr, XATTR_NAME_SMACKIPIN, &label);
RUNNER_ASSERT_ERRNO_MSG(result != -1, "smack_new_label_from_file failed: " << label);
labelPtr.reset(label);
result = expected_label.compare(label);
RUNNER_ASSERT_MSG(result == 0, "Socket label is incorrect. Expected: " <<
expected_label << " Actual: " << label);
- result = smack_new_label_from_file(sock, XATTR_NAME_SMACKIPOUT, &label);
+ result = smack_new_label_from_file(*sockPtr, XATTR_NAME_SMACKIPOUT, &label);
RUNNER_ASSERT_ERRNO_MSG(result != -1, "smack_new_label_from_file failed: " << label);
labelPtr.reset(label);
result = expected_label.compare(label);
users2AppsMap.insert(std::pair<std::string, std::map<std::string, std::set<std::string>>>(username, apps2PrivsMap));
//TEST DATA END
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
+ SynchronizationPipe pipe;
pid_t pid = fork();
if (pid != 0) { //parent process
+ pipe.claimParentEp();
TemporaryTestUser tmpUser(username, GUM_USERTYPE_NORMAL, false);
tmpUser.create();
//check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str());
};
+
//Start child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
+ pipe.post();
int status;
wait(&status);
tmpUser.remove();
- };
-
- if (pid == 0) { //child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno);
+ } else { //child process
+ pipe.claimChildEp();
+ pipe.wait();
//the above call, registers 1 new privilege for the given user, hence the incrementation of below variable
struct passwd *pw = getUserStruct(username);
++privileges_count;
//TEST DATA END
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
+ SynchronizationPipe pipe;
pid_t pid = fork();
if (pid != 0) { //parent process
+ pipe.claimParentEp();
std::vector<TemporaryTestUser> users = {
TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
//check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str());
};
+
//Start child
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
+ pipe.post();
int status;
wait(&status);
- for(auto &user : users) {
+ for (auto &user : users)
user.remove();
- };
- };
- if (pid == 0) {
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno);
+ } else { //child process
+ pipe.claimChildEp();
+ pipe.wait();
+
struct passwd *pw = getUserStruct(usernames.at(0));
register_current_process_as_privilege_manager(pw->pw_uid);
privileges_count += 2;
//TEST DATA END
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
+ SynchronizationPipe pipe;
pid_t pid = fork();
if (pid != 0) { //parent process
+ pipe.claimParentEp();
std::vector<TemporaryTestUser> users = {
TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
//check_app_after_install(MANY_APPS[i].c_str(), MANY_APPS_PKGS[i].c_str());
};
- //Start child
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
+ //Start child process
+ pipe.post();
//Wait for child to finish
int status;
wait(&status);
- for(auto &user : users) {
+ for (auto &user : users)
user.remove();
- };
- };
- if (pid == 0) { //child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child failed, errno: " << errno);
+ } else { //child process
+ pipe.claimChildEp();
+ pipe.wait();
struct passwd *pw = getUserStruct(usernames.at(1));
register_current_process_as_privilege_manager(pw->pw_uid, true);
//TEST DATA END
pid_t pid[2];
- sem_t *mutex[2];
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex[0] = sem_open("mutex_1", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #1, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex[1] = sem_open("mutex_2", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex #2, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex[0], 1, 0) == 0, "failed to setup mutex #1, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex[1], 1, 0) == 0, "failed to setup mutex #2, errno: " << errno);
+ SynchronizationPipe sync[2];
std::vector<PolicyEntry> policyEntries;
pid[0] = fork();
- if(pid[0] == 0) { //child #1 process
- RUNNER_ASSERT_MSG(sem_wait(mutex[0]) == 0, "sem_wait in child #1 failed, errno: " << errno);
+ if (pid[0] == 0) { //child #1 process
+ sync[0].claimChildEp();
+ sync[0].wait();
+
struct passwd *pw = getUserStruct(usernames.at(0));
register_current_process_as_privilege_manager(pw->pw_uid);
RUNNER_ASSERT_MSG(policyEntries.size() == 2, "Number of policies doesn't match - should be: 2 and is " << policyEntries.size());
exit(0);
- };
-
- if (pid[0] != 0) {//parent process
+ } else { //parent process
+ sync[0].claimParentEp();
pid[1] = fork();
if (pid[1] == 0) { //child #2 process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex[1]) == 0, "sem_wait in child #2 failed, errno: " << errno);
+ sync[1].claimChildEp();
+ sync[1].wait();
struct passwd *pw_target = getUserStruct(usernames.at(0));
struct passwd *pw = getUserStruct(usernames.at(1));
register_current_process_as_privilege_manager(pw->pw_uid);
Api::getPolicyForAdmin(filter, policyEntries, SECURITY_MANAGER_ERROR_ACCESS_DENIED);
RUNNER_ASSERT_MSG(policyEntries.size() == 0, "Policy is not empty");
exit(0);
- };
-
- if (pid[1] != 0) { //parent
-
+ } else { //parent
+ sync[1].claimParentEp();
std::vector<TemporaryTestUser> users = {
TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
int status;
//Start child #1
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex[0]) == 0, "Error while opening mutex #1, errno: " << errno);
+ sync[0].post();
//Wait until child #1 finishes
pid_t ret = wait(&status);
RUNNER_ASSERT_MSG((ret != -1) && WIFEXITED(status), "Updating privileges failed");
//Start child #2
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex[1]) == 0, "Error while opening mutex #2, errno: " << errno);
+ sync[1].post();
+
//Wait until child #2 finishes
ret = wait(&status);
RUNNER_ASSERT_MSG((ret =-1) && WIFEXITED(status), "Listing privileges failed");
- for(auto &user : users) {
+ for (auto &user : users)
user.remove();
- };
-
- sem_close(mutex[0]);
- sem_close(mutex[1]);
};
};
}
privileges_count += 2;
//TEST DATA END
- sem_t *mutex;
- errno = 0;
- RUNNER_ASSERT_MSG(((mutex = sem_open("mutex", O_CREAT, 0644, 1)) != SEM_FAILED), "Failure creating mutex, errno: " << errno);
- errno = 0;
- RUNNER_ASSERT_MSG(sem_init(mutex, 1, 0) == 0, "failed to setup mutex, errno: " << errno);
+ SynchronizationPipe pipe;
pid_t pid = fork();
if (pid != 0) {
+ pipe.claimParentEp();
std::vector<TemporaryTestUser> users = {
TemporaryTestUser(usernames.at(0), GUM_USERTYPE_NORMAL, false),
TemporaryTestUser(usernames.at(1), GUM_USERTYPE_ADMIN, false)
Api::install(requestInst);
};
};
+
//Start child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_post(mutex) == 0, "Error while opening mutex, errno: " << errno);
+ pipe.post();
+
int status;
//Wait for child process to finish
wait(&status);
//switch back to root
- for(auto &user : users) {
+ for (auto &user : users)
user.remove();
- };
- sem_close(mutex);
- }
-
- if (pid == 0) { //child process
- errno = 0;
- RUNNER_ASSERT_MSG(sem_wait(mutex) == 0, "sem_wait in child process failed, errno: " << errno);
+ } else { //child process
+ pipe.claimChildEp();
+ pipe.wait();
struct passwd *pw = getUserStruct(usernames.at(0));
register_current_process_as_privilege_manager(pw->pw_uid, true);
{"security-manager-cmd --i --app=app_id_10 --pkg=pkg_id_10", FAILURE},//no uid
{installcmd, SUCCESS},
{"security-manager-cmd -i -a" + app_id + " -g" + pkg_id + uidopt, SUCCESS},
- {installcmd + " --path " + path1 + " writable", SUCCESS},
+ {installcmd + " --path " + path1 + " rw", SUCCESS},
{installcmd + " --path " + path1, FAILURE},//no path type
- {installcmd + " --path " + path1 + " writable" + " --path " + path2 + " readable", SUCCESS},
- {installcmd + " --path " + path1 + " prie" + " --path " + path2 + " readable", FAILURE},//wrong path type
- {installcmd + " --path " + path1 + " writable" + " --privilege somepriv --privilege somepriv2" , SUCCESS},
+ {installcmd + " --path " + path1 + " rw" + " --path " + path2 + " ro", SUCCESS},
+ {installcmd + " --path " + path1 + " prie" + " --path " + path2 + " ro", FAILURE},//wrong path type
+ {installcmd + " --path " + path1 + " rw" + " --privilege somepriv --privilege somepriv2" , SUCCESS},
};
for (auto &op : operations) {
Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER);
Api::uninstall(ownerInst);
+ Api::uninstall(targetInst);
}
RUNNER_TEST(security_manager_31_simple_share)
Api::uninstall(requestUninst);
}
+void setupPriviligeGroups(const privileges_t &priviliges, const std::vector<std::string> &groups)
+{
+ TestSecurityManagerDatabase db;
+ for (const auto &privilege : priviliges) {
+ db.setup_privilege_groups(privilege, groups);
+ }
+}
+
+RUNNER_TEST(security_manager_48_groups_get)
+{
+ const auto &groups = SM_ALLOWED_GROUPS;
+ const auto &priviliges = SM_ALLOWED_PRIVILEGES;
+ setupPriviligeGroups(priviliges, groups);
+
+ char ** c_groups;
+ size_t count = 0;
+
+ Api::getSecurityManagerGroups(&c_groups, &count);
+ RUNNER_ASSERT_MSG(count == groups.size(), "security_manager_groups_get should set count to: "
+ << groups.size() << " but count is: " << count);
+
+ for (const auto &group : groups) {
+ bool found = false;
+ for (size_t i = 0; i < count; ++i) {
+ if (group == c_groups[i]) {
+ found = true;
+ break;
+ }
+ }
+ RUNNER_ASSERT_MSG(found, "PriviligeGroup: " << group << " was not found");
+ }
+ security_manager_groups_free(c_groups, count);
+}
+
int main(int argc, char *argv[])
{
return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);