#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/eventfd.h>
+#include <sys/types.h>
+#include <grp.h>
+
#include <cmath>
#include <thread>
#include <fstream>
#include <chrono>
#include <atomic>
+#include <algorithm>
#include <dpl/test/test_runner_child.h>
#include <dpl/test/test_runner.h>
} \
} while (0)
-void threadFn(int i, const std::string &expectedLabel)
+#ifdef SMACK_ENABLED
+ typedef std::string ProcessId;
+
+ ProcessId GetProcessIdFromSelf() {
+ char* label;
+ THREAD_ASSERT_MSG(smack_new_label_from_self(&label) > 0, "smack_new_label_from_self failed");
+ CStringPtr labelPtr(label);
+ ProcessId ret = label;
+ return ret;
+ }
+#else
+ struct ProcessId {
+ bool uidGE10000;
+ bool gidGE20000;
+
+ bool operator==(const ProcessId& other) const noexcept {
+ return other.uidGE10000 == uidGE10000 && other.gidGE20000 == gidGE20000;
+ }
+ };
+
+ ProcessId GetProcessIdFromSelf() {
+ static constexpr uid_t MIN_PROCESS_UID = 10000;
+ static constexpr gid_t MIN_AUTHOR_GID = 20000;
+
+ // get current process groups
+ int ret = getgroups(0, nullptr);
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+ std::vector<gid_t> actualGids(ret);
+ ret = getgroups(ret, actualGids.data());
+ RUNNER_ASSERT_MSG(ret != -1, "Unable to get supplementary groups");
+
+ auto agidCnt = std::count_if(actualGids.begin(), actualGids.end(), [](gid_t gid) {
+ return gid >= MIN_AUTHOR_GID;
+ });
+
+ return ProcessId{ getuid() >= MIN_PROCESS_UID, agidCnt == 1 };
+ }
+
+ std::ostream& operator<<(std::ostream& os, const ProcessId& id) {
+ os << id.uidGE10000 << "|" << id.gidGE20000;
+ return os;
+ }
+#endif
+
+void threadFn(int i, const ProcessId &expected)
{
if (i % 2 == 0) {
// block all signals
while (!finish)
usleep(1000);
- char* label;
- THREAD_ASSERT_MSG(smack_new_label_from_self(&label) > 0, "smack_new_label_from_self failed");
- CStringPtr labelPtr(label);
-
- THREAD_ASSERT_MSG(expectedLabel.compare(label) == 0,
- "Thread " << i << " has a wrong label: " << label);
+ auto id = GetProcessIdFromSelf();
+ THREAD_ASSERT_MSG(id == expected, "Thread " << i << " has a wrong id: " << id);
CapPtr expectedCaps(cap_init(), cap_free);
THREAD_ASSERT_MSG(expectedCaps, "cap_init() failed");
struct ThreadWrapper
{
-
ThreadWrapper()
{
}
thread.join();
}
- void run(int i, const std::string &expectedLabel)
+ void run(int i, const ProcessId &expected)
{
THREAD_ASSERT_MSG(!thread.joinable(), "Thread already started");
- thread = std::thread(threadFn, i, expectedLabel);
+ thread = std::thread(threadFn, i, expected);
}
std::thread thread;
tmpUser.create();
AppInstallHelper app("app100", tmpUser.getUid());
+ app.setAuthor("author");
ScopedInstaller appInstall(app);
- const std::string expectedLabel = app.generateAppLabel();
+#ifdef SMACK_ENABLED
+ const ProcessId expected = app.generateAppLabel();
+#else
+ const ProcessId expected{true, true};
+#endif
pid_t pid = fork();
RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
ThreadWrapper threads[THREADS];
for (size_t i = 0; i < THREADS; i++)
- threads[i].run(i, expectedLabel);
+ threads[i].run(i, expected);
+
+ Api::prepareApp(app.getAppId());
+ }
+ RUNNER_ASSERT_MSG(thread_errors.empty(), std::endl << thread_errors);
+ exit(0);
+ } else {
+ waitPid(pid);
+ Api::cleanupApp(app.getAppId(), tmpUser.getUid(), pid);
+ }
+}
+
+RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_no_author_test)
+{
+ TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
+ tmpUser.create();
+
+ AppInstallHelper app("app100", tmpUser.getUid());
+ ScopedInstaller appInstall(app);
+#ifdef SMACK_ENABLED
+ const ProcessId expected = app.generateAppLabel();
+#else
+ const ProcessId expected{true, false};
+#endif
+
+ pid_t pid = fork();
+ RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+ if (pid == 0) {
+ {
+ RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
+ Api::prepareAppCandidate();
+ ThreadWrapper threads[THREADS];
+
+ for (size_t i = 0; i < THREADS; i++)
+ threads[i].run(i, expected);
Api::prepareApp(app.getAppId());
}
tmpUser.create();
AppInstallHelper app("app100_n", tmpUser.getUid());
+ app.setAuthor("author");
ScopedInstaller appInstall(app);
- const std::string expectedLabel = app.generateAppLabel();
+#ifdef SMACK_ENABLED
+ const ProcessId expected = app.generateAppLabel();
+#else
+ const ProcessId expected{true, true};
+#endif
pid_t pid = fork();
RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
ThreadWrapper threads[THREADS];
for (size_t i = 0; i < THREADS; i++)
- threads[i].run(i, expectedLabel);
+ threads[i].run(i, expected);
Api::prepareAppCandidate(SECURITY_MANAGER_ERROR_INPUT_PARAM);
}
}
}
-RUNNER_CHILD_TEST(security_manager_101_create_namespace_test)
+RUNNER_CHILD_TEST(security_manager_101_create_namespace_test_p)
{
TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
tmpUser.create();
RUNNER_ASSERT_ERRNO_MSG(appBindInode == appProcInode, "bind namespace failed");
synchPipe.post();
+
waitPid(pid);
Api::cleanupApp(app.getAppId(), tmpUser.getUid(), pid);
}