* @version 1.0
* @brief Implementation of security-manager on basis of security-server
*/
+#include <grp.h>
#include <stdlib.h>
#include <signal.h>
+#include <linux/capability.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <dpl/errno_string.h>
#include <dpl/log/log.h>
#include <dpl/singleton.h>
#include <mount-namespace.h>
#include <socket-manager.h>
#include <service-file-locker.h>
+#include <utils.h>
#include <service.h>
#include <worker.h>
return 0;
}
+// Changes the UID to non-root while retaining all capabilities
+void dropRoot()
+{
+ if (-1 == prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0))
+ LogAndThrowErrno(SecurityManager::Exception, "Error in prctl");
+
+ // Save current caps
+ std::unique_ptr<std::remove_pointer_t<cap_t>, decltype(&cap_free)>
+ caps(cap_get_proc(), cap_free);
+ if (!caps)
+ LogAndThrowErrno(SecurityManager::Exception, "Error in cap_get_proc");
+
+ // Set the system_share group to get +x in app directories
+ gid_t group = getGidByName("system_share");
+ if (setgroups(1, &group))
+ LogAndThrowErrno(SecurityManager::Exception, "Failed to set supplementary group " << group);
+
+ // Change uid to non-root
+ uid_t uid = getUidByName("security_fw");
+ if (-1 == setuid(uid))
+ LogAndThrowErrno(SecurityManager::Exception, "Failed to set uid " << uid);
+
+ // Reclaim lost caps
+ if(-1 == cap_set_proc(caps.get()))
+ LogAndThrowErrno(SecurityManager::Exception, "Error in cap_set_proc ");
+}
+
int main()
{
UNHANDLED_EXCEPTION_HANDLER_BEGIN
return EXIT_FAILURE;
}
+ try {
+ dropRoot();
+ }
+ catch (const SecurityManager::Exception &exception) {
+ LogError("Error while dropping root");
+ return EXIT_FAILURE;
+ }
+
if (!MountNS::isPrivacyPrivilegeMountNamespaceEnabled()) {
// Lagacy systems without privacy privilege mount namespace.
// In this case security-manager will run without WORKER