Remove Proc_Kill(), use timeout to kill child processes
This avoids a race and potentionally killing the wrong process on systems that use randomized process IDs; now the child itself is responsible to exit in a timely manner using SIGALRM.
This commit is contained in:
parent
cf93881dfb
commit
6ebb31ab35
|
@ -1091,10 +1091,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
|
||||||
in_k, out_k);
|
in_k, out_k);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kill possibly running subprocess */
|
|
||||||
if (Proc_InProgress(&My_Connections[Idx].proc_stat))
|
|
||||||
Proc_Kill(&My_Connections[Idx].proc_stat);
|
|
||||||
|
|
||||||
/* Servers: Modify time of next connect attempt? */
|
/* Servers: Modify time of next connect attempt? */
|
||||||
Conf_UnsetServer( Idx );
|
Conf_UnsetServer( Idx );
|
||||||
|
|
||||||
|
|
|
@ -789,7 +789,10 @@ Hello_User(CLIENT * Client)
|
||||||
return DISCONNECTED;
|
return DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd, cb_Read_Auth_Result);
|
/* Fork child process for PAM authentication; and make sure that the
|
||||||
|
* process timeout is set higher than the login timeout! */
|
||||||
|
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
|
||||||
|
cb_Read_Auth_Result, Conf_PongTimeout + 1);
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
LogDebug("Authenticator for connection %d created (PID %d).",
|
LogDebug("Authenticator for connection %d created (PID %d).",
|
||||||
conn, pid);
|
conn, pid);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "conn.h"
|
||||||
|
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
|
@ -42,7 +43,7 @@ Proc_InitStruct (PROC_STAT *proc)
|
||||||
* Fork a child process.
|
* Fork a child process.
|
||||||
*/
|
*/
|
||||||
GLOBAL pid_t
|
GLOBAL pid_t
|
||||||
Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short))
|
Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
|
@ -67,7 +68,10 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short))
|
||||||
case 0:
|
case 0:
|
||||||
/* New child process: */
|
/* New child process: */
|
||||||
signal(SIGTERM, Proc_GenericSignalHandler);
|
signal(SIGTERM, Proc_GenericSignalHandler);
|
||||||
|
signal(SIGALRM, Proc_GenericSignalHandler);
|
||||||
close(pipefds[0]);
|
close(pipefds[0]);
|
||||||
|
alarm(timeout);
|
||||||
|
Conn_CloseAllSockets();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,21 +91,6 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short))
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Kill forked child process.
|
|
||||||
*/
|
|
||||||
GLOBAL void
|
|
||||||
Proc_Kill(PROC_STAT *proc)
|
|
||||||
{
|
|
||||||
assert(proc != NULL);
|
|
||||||
|
|
||||||
if (proc->pipe_fd > 0)
|
|
||||||
io_close(proc->pipe_fd);
|
|
||||||
if (proc->pid > 0)
|
|
||||||
kill(proc->pid, SIGTERM);
|
|
||||||
Proc_InitStruct(proc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic signal handler for forked child processes.
|
* Generic signal handler for forked child processes.
|
||||||
*/
|
*/
|
||||||
|
@ -112,6 +101,11 @@ Proc_GenericSignalHandler(int Signal)
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Log_Subprocess(LOG_DEBUG, "Child got TERM signal, exiting.");
|
Log_Subprocess(LOG_DEBUG, "Child got TERM signal, exiting.");
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
case SIGALRM:
|
||||||
|
#ifdef DEBUG
|
||||||
|
Log_Subprocess(LOG_DEBUG, "Child got ALARM signal, exiting.");
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -119,7 +113,7 @@ Proc_GenericSignalHandler(int Signal)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read bytes from a pipe of a forked child process.
|
* Read bytes from a pipe of a forked child process.
|
||||||
* In addition, this function makes sure that the child process is dead
|
* In addition, this function makes sure that the child process is ignored
|
||||||
* after all data has been read or a fatal error occurred.
|
* after all data has been read or a fatal error occurred.
|
||||||
*/
|
*/
|
||||||
GLOBAL size_t
|
GLOBAL size_t
|
||||||
|
@ -142,7 +136,7 @@ Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen)
|
||||||
else if (bytes_read == 0)
|
else if (bytes_read == 0)
|
||||||
LogDebug("Can't read from child process %ld: EOF", proc->pid);
|
LogDebug("Can't read from child process %ld: EOF", proc->pid);
|
||||||
#endif
|
#endif
|
||||||
Proc_Kill(proc);
|
Proc_InitStruct(proc);
|
||||||
return (size_t)bytes_read;
|
return (size_t)bytes_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,7 @@ typedef struct _Proc_Stat {
|
||||||
GLOBAL void Proc_InitStruct PARAMS((PROC_STAT *proc));
|
GLOBAL void Proc_InitStruct PARAMS((PROC_STAT *proc));
|
||||||
|
|
||||||
GLOBAL pid_t Proc_Fork PARAMS((PROC_STAT *proc, int *pipefds,
|
GLOBAL pid_t Proc_Fork PARAMS((PROC_STAT *proc, int *pipefds,
|
||||||
void (*cbfunc)(int, short)));
|
void (*cbfunc)(int, short), int timeout));
|
||||||
|
|
||||||
GLOBAL void Proc_Kill PARAMS((PROC_STAT *proc));
|
|
||||||
|
|
||||||
GLOBAL void Proc_GenericSignalHandler PARAMS((int Signal));
|
GLOBAL void Proc_GenericSignalHandler PARAMS((int Signal));
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define RESOLVER_TIMEOUT (Conf_PongTimeout*3)/4
|
||||||
|
|
||||||
#include "portab.h"
|
#include "portab.h"
|
||||||
|
|
||||||
#include "imp.h"
|
#include "imp.h"
|
||||||
|
@ -33,6 +35,7 @@
|
||||||
|
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "conn.h"
|
#include "conn.h"
|
||||||
|
#include "conf.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "ng_ipaddr.h"
|
#include "ng_ipaddr.h"
|
||||||
|
@ -63,7 +66,7 @@ Resolve_Addr(PROC_STAT * s, const ng_ipaddr_t *Addr, int identsock,
|
||||||
|
|
||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
|
|
||||||
pid = Proc_Fork(s, pipefd, cbfunc);
|
pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
LogDebug("Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid);
|
LogDebug("Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid);
|
||||||
return true;
|
return true;
|
||||||
|
@ -89,7 +92,7 @@ Resolve_Name( PROC_STAT *s, const char *Host, void (*cbfunc)(int, short))
|
||||||
|
|
||||||
assert(s != NULL);
|
assert(s != NULL);
|
||||||
|
|
||||||
pid = Proc_Fork(s, pipefd, cbfunc);
|
pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
/* Main process */
|
/* Main process */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
Loading…
Reference in New Issue