#include <sys/smack.h>
#include <sys/capability.h>
+#include <sys/prctl.h>
#include <thread>
#include <string>
bool finish = false;
const size_t THREADS = 10;
-const std::string SYNC_TEST_APP("app100");
+const std::string APP_TEST_USER = "app_test_user";
typedef std::unique_ptr<_cap_struct, decltype(&cap_free)> CapPtr;
std::thread thread;
};
+int setLauncherSecurityAttributes(TemporaryTestUser &user)
+{
+ // Add launcher capabilities (cap_dac_override, cap_setgid, cap_sys_admin, cap_mac_admin),
+ // launcher is user process, we must drop root privileges (cap_setgid, cap_setuid are needed).
+ // By default, the permitted capability set is cleared when credentials change is made
+ // (if a process drops a capability from its permitted set, it can never reacquire that capability),
+ // setting the "keep capabilities" flag prevents it from being cleared.
+ // Effective capability set is always cleared when credential change is made, we need to add them again.
+
+ setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep cap_setuid+ep");
+ int ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0);
+ if (ret != 0)
+ return ret;
+
+ ret = drop_root_privileges(user.getUid(), user.getGid());
+ if (ret != 0)
+ return ret;
+
+ setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep");
+ return ret;
+}
+
} // anonymous namespace
RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_PREPARE_APP)
RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_test)
{
- AppInstallHelper app(SYNC_TEST_APP.c_str());
+ TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
+ tmpUser.create();
+
+ AppInstallHelper app("app100", tmpUser.getUid());
ScopedInstaller appInstall(app);
const std::string expectedLabel = app.generateAppLabel();
RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
if (pid == 0) {
{
+ RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
+
ThreadWrapper threads[THREADS];
for (size_t i = 0; i < THREADS; i++)