ext/common/agents/HelperAgent/Main.cpp in passenger-5.0.7 vs ext/common/agents/HelperAgent/Main.cpp in passenger-5.0.8
- old
+ new
@@ -29,10 +29,13 @@
#ifdef __linux__
#define SUPPORTS_PER_THREAD_CPU_AFFINITY
#include <sched.h>
#include <pthread.h>
#endif
+#ifdef USE_SELINUX
+ #include <selinux/selinux.h>
+#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
@@ -266,19 +269,69 @@
do {
ret = chmod(path.c_str(), parseModeString("u=rw,g=rw,o=rw"));
} while (ret == -1 && errno == EINTR);
}
+#ifdef USE_SELINUX
+ // Set next socket context to *:system_r:passenger_instance_httpd_socket_t
+ static void
+ setSelinuxSocketContext() {
+ security_context_t currentCon;
+ string newCon;
+ int e;
+
+ if (getcon(¤tCon) == -1) {
+ e = errno;
+ P_DEBUG("Unable to obtain SELinux context: " <<
+ strerror(e) << " (errno=" << e << ")");
+ return;
+ }
+
+ P_DEBUG("Current SELinux process context: " << currentCon);
+
+ if (strstr(currentCon, ":unconfined_r:unconfined_t:") == NULL) {
+ goto cleanup;
+ }
+
+ newCon = replaceString(currentCon,
+ ":unconfined_r:unconfined_t:",
+ ":object_r:passenger_instance_httpd_socket_t:");
+ if (setsockcreatecon((security_context_t) newCon.c_str()) == -1) {
+ e = errno;
+ P_WARN("Cannot set SELinux socket context to " << newCon <<
+ ": " << strerror(e) << " (errno=" << e << ")");
+ goto cleanup;
+ }
+
+ cleanup:
+ freecon(currentCon);
+ }
+
+ static void
+ resetSelinuxSocketContext() {
+ setsockcreatecon(NULL);
+ }
+#endif
+
static void
startListening() {
TRACE_POINT();
WorkingObjects *wo = workingObjects;
vector<string> addresses = agentsOptions->getStrSet("server_addresses");
vector<string> adminAddresses = agentsOptions->getStrSet("server_admin_addresses", false);
+ #ifdef USE_SELINUX
+ // Set SELinux context on the first socket that we create
+ // so that the web server can access it.
+ setSelinuxSocketContext();
+ #endif
+
for (unsigned int i = 0; i < addresses.size(); i++) {
wo->serverFds[i] = createServer(addresses[i], 0, true,
__FILE__, __LINE__);
+ #ifdef USE_SELINUX
+ resetSelinuxSocketContext();
+ #endif
P_LOG_FILE_DESCRIPTOR_PURPOSE(wo->serverFds[i],
"Server address: " << addresses[i]);
if (getSocketAddressType(addresses[i]) == SAT_UNIX) {
makeFileWorldReadableAndWritable(parseUnixSocketAddress(addresses[i]));
}