Bind to socket in thread instead of main process to ensure forks do not inherit sockets they shouldn't.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2020-06-26 10:51:01 +02:00
parent 12a54eaea9
commit 85bc53cbd1
4 changed files with 36 additions and 31 deletions
+21 -26
View File
@@ -31,8 +31,7 @@
// File descriptors
int socketfd, telnetfd4 = 0, telnetfd6 = 0;
bool dualstack = false;
bool ipv4telnet = false, ipv6telnet = false;
bool sock_avail = false;
bool ipv4telnet = false, ipv6telnet = false, sock_avail = false;
bool istelnet[MAXCONNS];
static void saveport(void)
@@ -95,6 +94,7 @@ static bool bind_to_telnet_port_IPv4(int *socketdescriptor)
return false;
}
saveport();
logg("Listening on port %i for incoming IPv4 telnet connections", config.port);
return true;
}
@@ -157,11 +157,12 @@ static bool bind_to_telnet_port_IPv6(int *socketdescriptor)
return false;
}
saveport();
logg("Listening on port %i for incoming IPv6 telnet connections", config.port);
return true;
}
static void bind_to_unix_socket(int *socketdescriptor)
static bool bind_to_unix_socket(int *socketdescriptor)
{
*socketdescriptor = socket(AF_LOCAL, SOCK_STREAM, 0);
@@ -169,7 +170,7 @@ static void bind_to_unix_socket(int *socketdescriptor)
{
logg("WARNING: Error opening Unix socket.");
logg(" Continuing anyway.");
return;
return false;
}
// Make sure unix socket file handle does not exist, if it exists, remove it
@@ -191,7 +192,7 @@ static void bind_to_unix_socket(int *socketdescriptor)
{
logg("WARNING: Cannot bind on Unix socket %s: %s (%i)", FTLfiles.socketfile, strerror(errno), errno);
logg(" Continuing anyway.");
return;
return false;
}
// The listen system call allows the process to listen on the Unix socket for connections
@@ -199,11 +200,11 @@ static void bind_to_unix_socket(int *socketdescriptor)
{
logg("WARNING: Cannot listen on Unix socket: %s (%i)", strerror(errno), errno);
logg(" Continuing anyway.");
return;
return false;
}
logg("Listening on Unix socket");
sock_avail = true;
return true;
}
// Called from main() at graceful shutdown
@@ -413,24 +414,6 @@ static void *socket_connection_handler_thread(void *socket_desc)
return false;
}
void bind_sockets(void)
{
// Initialize IPv4 telnet socket
if(bind_to_telnet_port_IPv4(&telnetfd4))
ipv4telnet = true;
// Initialize IPv6 telnet socket
// only if IPv6 interfaces are available
if(ipv6_available())
if(bind_to_telnet_port_IPv6(&telnetfd6))
ipv6telnet = true;
saveport();
// Initialize Unix socket
bind_to_unix_socket(&socketfd);
}
void *telnet_listening_thread_IPv4(void *args)
{
// We will use the attributes object later to start all threads in detached mode
@@ -444,6 +427,11 @@ void *telnet_listening_thread_IPv4(void *args)
// Set thread name
prctl(PR_SET_NAME,"telnet-IPv4",0,0,0);
// Initialize IPv4 telnet socket
if(!bind_to_telnet_port_IPv4(&telnetfd4))
return NULL;
ipv4telnet = true;
// Listen as long as FTL is not killed
while(!killed)
{
@@ -485,6 +473,12 @@ void *telnet_listening_thread_IPv6(void *args)
// Set thread name
prctl(PR_SET_NAME,"telnet-IPv6",0,0,0);
// Initialize IPv6 telnet socket
// only if IPv6 interfaces are available
if(!ipv6_available() || !bind_to_telnet_port_IPv6(&telnetfd6))
return NULL;
ipv6telnet = true;
// Listen as long as FTL is not killed
while(!killed)
{
@@ -527,8 +521,9 @@ void *socket_listening_thread(void *args)
prctl(PR_SET_NAME,"socket listener",0,0,0);
// Return early to avoid CPU spinning if Unix socket is not available
if(!sock_avail)
if(!bind_to_unix_socket(&socketfd))
return NULL;
sock_avail = true;
// Listen as long as FTL is not killed
while(!killed)
+2
View File
@@ -1910,6 +1910,8 @@ static void check_dns_listeners(time_t now)
}
close(confd);
FTL_TCP_worker_created();
/* The child can use up to TCP_MAX_QUERIES ids, so skip that many. */
daemon->log_id += TCP_MAX_QUERIES;
}
+12 -5
View File
@@ -1646,18 +1646,15 @@ void FTL_fork_and_bind_sockets(struct passwd *ent_pw)
// join with the terminated thread
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// Bind to sockets
bind_sockets();
// Start TELNET IPv4 thread
if(ipv4telnet && pthread_create( &telnet_listenthreadv4, &attr, telnet_listening_thread_IPv4, NULL ) != 0)
if(pthread_create( &telnet_listenthreadv4, &attr, telnet_listening_thread_IPv4, NULL ) != 0)
{
logg("Unable to open IPv4 telnet listening thread. Exiting...");
exit(EXIT_FAILURE);
}
// Start TELNET IPv6 thread
if(ipv6telnet && pthread_create( &telnet_listenthreadv6, &attr, telnet_listening_thread_IPv6, NULL ) != 0)
if(pthread_create( &telnet_listenthreadv6, &attr, telnet_listening_thread_IPv6, NULL ) != 0)
{
logg("Unable to open IPv6 telnet listening thread. Exiting...");
exit(EXIT_FAILURE);
@@ -1832,3 +1829,13 @@ void FTL_TCP_worker_terminating(void)
// Close dedicated database connection of this fork
gravityDB_close();
}
// Called when a (forked) TCP worker is created
void FTL_TCP_worker_created(void)
{
if(config.debug != 0)
{
// Print this if any debug setting is enabled
logg("TCP worker forked");
}
}
+1
View File
@@ -51,6 +51,7 @@ bool _FTL_CNAME(const char *domain, const struct crec *cpp, const int id, const
void FTL_dnsmasq_reload(void);
void FTL_fork_and_bind_sockets(struct passwd *ent_pw);
void FTL_TCP_worker_created(void);
void FTL_TCP_worker_terminating(void);
void set_debug_dnsmasq_lines(char enabled);