/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <algorithm>
#include <cstring>
+#include <fcntl.h>
#include <ftw.h>
#include <grp.h>
#include <string>
#include <sys/capability.h>
+#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <unordered_map>
#include <cstdlib>
+#include <array>
#include <unordered_set>
+#include <utility>
#include <vector>
#include <security-manager-types.h>
+#include <app-runtime.h>
#include <sys/smack.h>
+#include <privilege_info.h>
+#include <scoped_process_label.h>
#include <cynara_test_client.h>
#include <dpl/test/test_runner.h>
#include <memory.h>
#include <sm_api.h>
#include <sm_commons.h>
-#include <sm_db.h>
#include <synchronization_pipe.h>
#include <sm_request.h>
#include <tests_common.h>
+#include <policy_configuration.h>
#include "tzplatform.h"
+#include <label_generator.h>
+#include <template_parser.h>
+#include <temp_test_user.h>
using namespace SecurityManagerTest;
-// Common const values
+#define CONF_DIR "/usr/share/security-manager/policy/"
+#define SMACK_RULES_PATH "/sys/fs/smackfs/load2"
-const privileges_t SM_ALLOWED_PRIVILEGES = {
- "http://tizen.org/privilege/display",
- "http://tizen.org/privilege/nfc"
-};
-
-const privileges_t SM_DENIED_PRIVILEGES = {
- "http://tizen.org/privilege/bluetooth",
- "http://tizen.org/privilege/power"
-};
-
-const privileges_t SM_NO_PRIVILEGES = {
-};
-
-const std::vector<std::string> SM_ALLOWED_GROUPS = {"db_browser", "db_alarm"};
-
-const std::string uidToStr(const uid_t uid)
-{
- return std::to_string(static_cast<unsigned int>(uid));
-}
-
-// Common implementation details
-
-std::string generateProcessLabel(const std::string &appId, const std::string &pkgId, bool isHybrid)
-{
- std::string label = "User::Pkg::" + pkgId;
- if (isHybrid) {
- label += "::App::" + appId;
- }
- return label;
-}
-
-std::string generatePathRWLabel(const std::string &pkgId)
-{
- return "User::Pkg::" + pkgId;
-}
-
-std::string generatePathROLabel(const std::string &pkgId)
-{
- return generatePathRWLabel(pkgId) + "::RO";
-}
-
-std::string generatePathSharedROLabel(const std::string &pkgId)
-{
- return generatePathRWLabel(pkgId) + "::SharedRO";
-}
-
-std::string generatePathTrustedLabel(int64_t authorId)
-{
- return "User::Author::" + std::to_string(authorId);
-}
-
-std::string getPublicPathLabel()
-{
- return "User::Home";
-}
-
-static std::string genPath(int app_num, const char *postfix) {
- char buf[16];
- sprintf(buf, "%02d", app_num);
- return TzPlatformConfig::globalAppDir() + "/sm_test_" + std::string(buf) + "_pkg_id_full/" + std::string(postfix);
-}
-
-std::string genRWPath(int app_num) {
- return genPath(app_num, "app_dir");
-}
-std::string genROPath(int app_num) {
- return genPath(app_num, "app_dir_ro");
-}
-std::string genPublicROPath(int app_num) {
- return genPath(app_num, "app_dir_public_ro");
-}
-
-std::string genOwnerRWOthersROPath(int app_num) {
- return genPath(app_num, "app_dir_rw_others_ro");
-}
-
-static std::string generatePkgLabelOwnerRWothersRO(const std::string &pkgId)
-{
- return "User::Pkg::" + pkgId + "::SharedRO";
-}
+#define ALLOW 0
+#define DENY -1
// Common DB/nftw checks
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;
-}
-
int nftw_remove_labels(const char *fpath, const struct stat* /*sb*/,
int /*typeflag*/, struct FTW* /*ftwbuf*/)
{
return 0;
}
-static const std::string SM_DENIED_PATH = TzPlatformConfig::globalAppDir() + "/non_app_dir";
-
void check_app_permissions(const std::string &app_id, const std::string &pkg_id,
const std::string &user, const privileges_t &allowed_privs,
const privileges_t &denied_privs, bool isHybrid)
}
}
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id)
+static void check_app_smack_accesses(const std::string &appId, const std::string &pkgId,
+ bool isHybrid = false)
{
- TestSecurityManagerDatabase dbtest;
- dbtest.test_db_after__app_install(app_id, pkg_id);
+ static const std::vector<AccessRequest> rules[] =
+ {parseSmackRulesFile(CONF_DIR "pkg-rules-template.smack"),
+ parseSmackRulesFile(CONF_DIR "app-rules-template.smack")};
+
+ const std::pair<std::string, std::string> switchAliases[] =
+ {std::make_pair("~PATH_RW~", generatePathRWLabel(pkgId)),
+ std::make_pair("~PATH_RO~", generatePathROLabel(pkgId)),
+ std::make_pair("~PROCESS~", generateProcessLabel(appId, pkgId, isHybrid))};
+
+ for (auto rule : rules[isHybrid]) {
+ if (rule.object == "~PATH_TRUSTED~") {
+ continue;
+ }
+
+ for (const auto &alias : switchAliases) {
+ if (rule.subject == alias.first) {
+ rule.subject = alias.second;
+ }
+ if (rule.object == alias.first) {
+ rule.object = alias.second;
+ }
+ }
+
+ if (rule.object == "_") {
+ rule.access = "rx" + rule.access;
+ }
+
+ check_exact_smack_accesses(rule.subject, rule.object, rule.access);
+ }
+}
+
+static void assert_no_label_in_rule(const AccessRequest &rule, const std::string &label)
+{
+ RUNNER_ASSERT_MSG(rule.object != label && rule.subject != label,
+ "Smack rule left after uninstallation process." <<
+ " Subject: " << rule.subject <<
+ " object: " << rule.object <<
+ " access: " << rule.access);
+}
+
+static void check_pkg_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
+{
+ const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
+ const std::string labels[] = {generatePathRWLabel(pkgId),
+ generatePathROLabel(pkgId),
+ generateProcessLabel(appId, pkgId, true),
+ generateProcessLabel(appId, pkgId)};
+ for (const auto &rule : rules) {
+ for (const auto &label : labels) {
+ assert_no_label_in_rule(rule, label);
+ }
+ }
+}
+
+static void check_hybrid_app_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
+{
+ const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
+ const std::string appLabel = generateProcessLabel(appId, pkgId, true);
+ for (const auto &rule : rules) {
+ assert_no_label_in_rule(rule, appLabel);
+ }
+}
+
+static void check_app(const std::string &appId, const std::string &pkgId,
+ bool shouldBeInstalled, bool isHybrid, bool removePkg)
+{
+ char *retPkgId;
+ int ret = security_manager_get_app_pkgid(&retPkgId, appId.c_str());
+
+ if (shouldBeInstalled) {
+ RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_SUCCESS, "The given appId is not installed.");
+
+ if (ret == SECURITY_MANAGER_SUCCESS) {
+ CStringPtr retPkgIdPtr(retPkgId);
+ RUNNER_ASSERT_MSG(strcmp(pkgId.c_str(), retPkgId) == 0,
+ "The given appId does not belong to the given pkgId.");
+ }
+ check_app_smack_accesses(appId, pkgId, isHybrid);
+ } else {
+ RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "The given appId is installed.");
+
+ if (removePkg) {
+ check_pkg_smack_rules_after_uninstall(appId, pkgId);
+ } else if (isHybrid) {
+ check_hybrid_app_smack_rules_after_uninstall(appId, pkgId);
+ }
+ }
+}
+
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id, bool isHybrid)
+{
+ check_app(app_id, pkg_id, true, isHybrid, false);
}
static void check_app_gids(const std::string &app_id, const std::vector<gid_t> &allowed_gids)
void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
const privileges_t &allowed_privs,
const privileges_t &denied_privs,
- const std::vector<std::string> &allowed_groups,
bool isHybrid)
{
- TestSecurityManagerDatabase dbtest;
- dbtest.test_db_after__app_install(app_id, pkg_id);
-
- /*Privileges should be granted to all users if root installs app*/
+ check_app(app_id, pkg_id, true, isHybrid, false);
+ /* Privileges should be granted to all users if root installs app */
check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs, isHybrid);
- /* Setup mapping of gids to privileges */
- /* Do this for each privilege for extra check */
- for (const auto &privilege : allowed_privs) {
- dbtest.setup_privilege_groups(privilege, allowed_groups);
- }
+ PolicyConfiguration policy;
+ const PolicyConfiguration::GroupVector allowed_groups = policy.privToGroup(allowed_privs);
+ RUNNER_ASSERT_MSG(allowed_groups.size() == allowed_privs.size(),
+ "Some privileges given were not found in the policy");
std::vector<gid_t> allowed_gids;
-
for (const auto &groupName : allowed_groups) {
errno = 0;
struct group* grp = getgrnam(groupName.c_str());
RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path);
}
-void check_app_path_after_install(int app_num, const char *pkgId, bool others_enabled)
-{
- std::string SM_RW_PATH = genRWPath(app_num);
- std::string SM_RO_PATH = genROPath(app_num);
- std::string SM_PUBLIC_RO_PATH = genPublicROPath(app_num);
- int result;
-
- nftw_expected_label = generatePathRWLabel(pkgId);
- nftw_expected_transmute = true;
- nftw_expected_exec = false;
-
- result = nftw(SM_RW_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_RW_PATH);
-
- nftw_expected_label = generatePathRWLabel(pkgId) + "::RO";
- nftw_expected_transmute = false;
- nftw_expected_exec = false;
-
- result = nftw(SM_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_RO_PATH);
-
- nftw_expected_label = "User::Home";
- nftw_expected_transmute = true;
- nftw_expected_exec = false;
-
- result = nftw(SM_PUBLIC_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_PUBLIC_RO_PATH);
-
- result = nftw(SM_DENIED_PATH.c_str(), &nftw_check_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_DENIED_PATH);
-
- // owner RW, others RO
- if(others_enabled) {
- std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(app_num);
- nftw_expected_label = generatePkgLabelOwnerRWothersRO(pkgId);
- nftw_expected_transmute = true;
- nftw_expected_exec = false;
-
- result = nftw(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_OWNER_RW_OTHERS_RO_PATH);
- }
-}
-
void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
- const bool is_pkg_removed)
+ bool isHybrid, bool removePkg)
{
- TestSecurityManagerDatabase dbtest;
- dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed);
+ check_app(app_id, pkg_id, false, isHybrid, removePkg);
}
void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
- const privileges_t &privileges, const bool is_pkg_removed,
- bool isHybrid)
+ const privileges_t &privileges, bool isHybrid,
+ bool removePkg)
{
- TestSecurityManagerDatabase dbtest;
- dbtest.test_db_after__app_uninstall(app_id, pkg_id, is_pkg_removed);
-
+ check_app(app_id, pkg_id, false, isHybrid, removePkg);
- /*Privileges should not be granted anymore to any user*/
- check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, SM_NO_PRIVILEGES, privileges, isHybrid);
+ /* Privileges should not be granted anymore to any user */
+ check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, {}, privileges, isHybrid);
}
std::string access_opposite(std::string &access) {
static const std::map<char, int> access_mapping = {{'r', 0}, {'w', 1}, {'x', 2}, {'a', 3},
{'t', 4}, {'l', 5}};
- //May write implies may lock
+ // May write implies may lock
if (access.find('w') != std::string::npos && access.find('l') == std::string::npos) {
access.append("l");
}
return caps;
}
-static void prepare_app_path(int app_num, bool others_enabled = false)
-{
- std::string SM_RW_PATH = genRWPath(app_num);
- std::string SM_RO_PATH = genROPath(app_num);
- std::string SM_PUBLIC_RO_PATH = genPublicROPath(app_num);
- int result;
-
- result = nftw(SM_RW_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_RW_PATH);
-
- result = nftw(SM_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_RO_PATH);
-
- result = nftw(SM_PUBLIC_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_PUBLIC_RO_PATH);
-
- if(others_enabled) {
- std::string SM_OWNER_RW_OTHERS_RO_PATH = genOwnerRWOthersROPath(app_num);
- result = nftw(SM_OWNER_RW_OTHERS_RO_PATH.c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to clean Smack labels in " << SM_OWNER_RW_OTHERS_RO_PATH);
- }
-
- result = nftw(SM_DENIED_PATH.c_str(), &nftw_set_labels_non_app_dir, FTW_MAX_FDS, FTW_PHYS);
- RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << SM_DENIED_PATH);
+static int getOppositeAccessType(int accessType) {
+ return accessType ^ (R_OK | W_OK | X_OK);
}
-void prepare_app_env(int app_num, bool others_enabled)
-{
- prepare_app_path(app_num, others_enabled);
-}
+static const std::unordered_map<int, const char* const> accessTypeToString {
+ std::make_pair(0, "F_OK"),
+ std::make_pair(1, "X_OK"),
+ std::make_pair(2, "W_OK"),
+ std::make_pair(3, "W_OK|X_OK"),
+ std::make_pair(4, "R_OK"),
+ std::make_pair(5, "R_OK|X_OK"),
+ std::make_pair(6, "R_OK|W_OK"),
+ std::make_pair(7, "R_OK|W_OK|X_OK")
+};
-void install_app(const std::string &app_id, const std::string &pkg_id, uid_t uid, app_install_type type,
- bool check_after)
+void accessCheck(const std::string &id, const std::string &path, int accessType,
+ int expected)
{
- InstallRequest request;
- request.setAppId(app_id);
- request.setPkgId(pkg_id);
- request.setUid(uid);
- if (type != SM_APP_INSTALL_NONE)
- request.setInstallType(type);
- Api::install(request);
-
- if (check_after)
- check_app_after_install(app_id, pkg_id);
+ RUNNER_ASSERT_MSG(::access(path.c_str(), accessType) == expected,
+ "access from " << id << " to path " << path
+ << (expected == 0 ? " not granted" : " unnecessarily granted")
+ << " (" << accessTypeToString.at(accessType) << ")");
}
-void uninstall_app(const std::string &app_id, const std::string &pkg_id, bool expect_pkg_removed,
- app_install_type type, bool check_after)
-{
- InstallRequest request;
- request.setAppId(app_id);
- if (type != SM_APP_INSTALL_NONE)
- request.setInstallType(type);
- Api::uninstall(request);
+void accessTest(const std::string &id, const std::string &testPath, int accessType) {
+ int oppositeAccessType = getOppositeAccessType(accessType);
- if (check_after)
- check_app_after_uninstall(app_id, pkg_id, expect_pkg_removed);
+ if (accessType != 0) {
+ accessCheck(id, testPath, accessType, ALLOW);
+ }
+ if (oppositeAccessType != 0) {
+ static const std::vector<int> singleAccessTypes = {R_OK, W_OK, X_OK};
+ for (auto singleAccessType : singleAccessTypes) {
+ if (oppositeAccessType & singleAccessType) {
+ accessCheck(id, testPath, singleAccessType, DENY);
+ }
+ }
+ }
}
-static const std::string EXEC_FILE("exec");
-static const std::string NORMAL_FILE("normal");
-static const std::string LINK_PREFIX("link_to_");
+void runAccessTest(const std::string &label, uid_t uid, gid_t gid,
+ const std::string &testPath, int accessType) {
+ auto fun = [&](){
+ ScopedProcessLabel spl(label, false);
+ RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(uid, gid),
+ "drop_root_privileges failed.");
-static void createTestDir(const std::string &dir)
-{
- mode_t dirMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
- mode_t execFileMode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
- mode_t normalFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+ accessTest(label, testPath, accessType);
+ };
- mktreeSafe(dir, dirMode);
- creatSafe(dir + "/" + EXEC_FILE, execFileMode);
- creatSafe(dir + "/" + NORMAL_FILE, normalFileMode);
- symlinkSafe(dir + "/" + EXEC_FILE, dir + "/" + LINK_PREFIX + EXEC_FILE);
- symlinkSafe(dir + "/" + NORMAL_FILE, dir + "/" + LINK_PREFIX + NORMAL_FILE);
+ runInChildParentWait(fun);
}
-static void createInnerAppDir(const std::string &dir, const std::string &nonAppDir)
-{
- createTestDir(dir);
+void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType) {
+ auto fun = [&](){
+ Api::setProcessLabel(app.getAppId());
+ RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(app.getUID(), app.getGID()),
+ "drop_root_privileges failed.");
+ accessTest(app.getAppId(), testPath, accessType);
+ };
- symlinkSafe(nonAppDir, dir + "/" + LINK_PREFIX + "non_app_dir");
- symlinkSafe(nonAppDir + "/" + EXEC_FILE,
- dir + "/" + LINK_PREFIX + "non_app_" + EXEC_FILE);
- symlinkSafe(nonAppDir + "/" + NORMAL_FILE,
- dir + "/" + LINK_PREFIX + "non_app_" + NORMAL_FILE);
+ runInChildParentWait(fun);
}
-static const std::string nonAppDirPath(const TemporaryTestUser &user)
-{
- return TMP_DIR + "/" + user.getUserName();
+static const std::vector<std::string> SM_SYSTEM_LABELS = {"System", "System::Privileged", "User"};
+
+void runSystemAccessTest(uid_t uid, gid_t gid, const std::string &testPath, int accessType) {
+ for (const auto &label : SM_SYSTEM_LABELS)
+ runAccessTest(label, uid, gid, testPath, accessType);
}
-static void generateAppDir(const TemporaryTestUser &user,
- const std::string &appId, const std::string &pkgId)
-{
- const std::string dir = TzPlatformConfig::appDirPath(user, appId, pkgId);
- const std::string nonAppDir = nonAppDirPath(user);
+bool isAskuserDisabled() {
+ static bool isAskuserDisabled = false;
+ static bool isChecked = false;
- createInnerAppDir(dir, nonAppDir);
- createInnerAppDir(dir + "/.inner_dir", nonAppDir);
- createInnerAppDir(dir + "/inner_dir", nonAppDir);
-}
+ if (isChecked)
+ return isAskuserDisabled;
-static void generateNonAppDir(const TemporaryTestUser &user)
-{
- const std::string dir = nonAppDirPath(user);
+ std::string sysShare = TzPlatformConfig::getPath(TZ_SYS_SHARE);
+ std::string askDisableFile = sysShare + "/askuser_disable";
- createTestDir(dir);
- createTestDir(dir + "/.inner_dir");
- createTestDir(dir + "/inner_dir");
+ isAskuserDisabled = (access(askDisableFile.c_str(), F_OK) != -1);
+ isChecked = true;
+ return isAskuserDisabled;
}
-void createTestDirs(const TemporaryTestUser &user,
- const std::string &appId, const std::string &pkgId)
-{
- generateAppDir(user, appId, pkgId);
- generateNonAppDir(user);
+bool isPrivilegePrivacy(const std::string &priv) {
+ return (1 == privilege_info_is_privacy(priv.c_str()));
}
-void removeTestDirs(const TemporaryTestUser &user,
- const std::string &appId, const std::string &pkgId)
-{
- removeDir(TzPlatformConfig::appDirPath(user, appId, pkgId));
- removeDir(nonAppDirPath(user));
+int countPrivacyPrivileges(const PrivilegeVector &privs) {
+ return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy);
}
-pid_t runInChild(const std::function<void(void)> &process) {
- pid_t pid = fork();
- RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
-
- if (pid == 0) {
- process();
- exit(EXIT_SUCCESS);
- }
- return pid;
+int countPrivacyPrivileges(const std::vector<std::string> &privs) {
+ return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy);
}
-void runInChildParentWait(const std::function<void(void)> &process) {
- SynchronizationPipe pipe;
- pid_t pid = fork();
- RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "fork failed");
+int setLauncherSecurityAttributes(uid_t uid, gid_t gid)
+{
+ // 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.
- if (pid == 0) {
- pipe.claimChildEp();
+ 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;
- process();
+ ret = drop_root_privileges(uid, gid);
+ if (ret != 0)
+ return ret;
- pipe.post();
- exit(EXIT_SUCCESS);
- } else {
- pipe.claimParentEp();
- pipe.wait();
- }
+ setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep");
+ return ret;
}
+int setLauncherSecurityAttributes(TemporaryTestUser &user)
+{
+ return setLauncherSecurityAttributes(user.getUid(), user.getGid());
+}
+