summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2013-03-02 02:26:17 +0000
committererdgeist <>2013-03-02 02:26:17 +0000
commit87dc06e5e85a98eea2d5ebcca81c856ff2a2cbb4 (patch)
treeb4411a4e1564e628cbc35abad72b4ca7995ebc3e
parent78615157edb1b25a8d64ad59b8649713cd39b42c (diff)
Keep a list of our probe's jids and kill them when the daemon exits
-rw-r--r--jaildaemon.c82
1 files changed, 74 insertions, 8 deletions
diff --git a/jaildaemon.c b/jaildaemon.c
index 506ca98..3ae8612 100644
--- a/jaildaemon.c
+++ b/jaildaemon.c
@@ -16,11 +16,17 @@
16#define IPC_PACKETSIZE 4096 16#define IPC_PACKETSIZE 4096
17#define MAGIC_EXIT_CODE 42 17#define MAGIC_EXIT_CODE 42
18enum { IAM_DAEMON, IAM_CLIENT, IAM_FORKSLAVE }; 18enum { IAM_DAEMON, IAM_CLIENT, IAM_FORKSLAVE };
19static int g_uds; 19static int g_uds;
20static int g_whoami = IAM_CLIENT; 20static int g_whoami = IAM_CLIENT;
21static int g_fork_slave_fd; 21static int g_fork_slave_fd;
22static char g_ipc_packet[IPC_PACKETSIZE]; 22static char g_ipc_packet[IPC_PACKETSIZE];
23static int * const g_ipc_packet_int = (int*)g_ipc_packet; 23static int * const g_ipc_packet_int = (int*)g_ipc_packet;
24
25/* For house keeping a list of all processes we attach to jails (probes), with
26 an initial vector size of 128. The vector never shrinks. */
27#define PROBES_VECTOR_SIZE 128
28static pid_t * g_probes;
29static size_t g_probes_size;
24 30
25typedef struct { 31typedef struct {
26 int m_jid; 32 int m_jid;
@@ -31,6 +37,8 @@ typedef struct {
31 37
32/* Forward declarations */ 38/* Forward declarations */
33static void signal_handler( int signal ); 39static void signal_handler( int signal );
40static void term_handler( int signal );
41static void kill_all_probes( void );
34static int check_for_jail( int jid ); 42static int check_for_jail( int jid );
35static int copy_daemontask( daemon_task ** out, daemon_task * const in ); 43static int copy_daemontask( daemon_task ** out, daemon_task * const in );
36static int add_task_to_kqueue( int kq, daemon_task * task_in ); 44static int add_task_to_kqueue( int kq, daemon_task * task_in );
@@ -49,6 +57,11 @@ static void signal_handler( int signal ) {
49 _exit( MAGIC_EXIT_CODE ); 57 _exit( MAGIC_EXIT_CODE );
50} 58}
51 59
60static void term_handler( int signal ) {
61 if( signal == SIGTERM )
62 exit(0);
63}
64
52/* Report error through the appropriate notification channel. 65/* Report error through the appropriate notification channel.
53 Currently this just writes to stderr, which hopefully still is there. */ 66 Currently this just writes to stderr, which hopefully still is there. */
54static void exerr( char * message ) { 67static void exerr( char * message ) {
@@ -266,10 +279,23 @@ static void fork_and_execve( int kq, daemon_task * t_in ) {
266 } 279 }
267} 280}
268 281
282static void kill_all_probes( void ) {
283 size_t i;
284syslog( LOG_ERR, "KILLING PROBES" );
285 if( g_probes )
286 for( i = 0; i < g_probes_size; ++i )
287 if( g_probes[i] )
288 kill( g_probes[i], SIGTERM );
289 g_probes_size = 0;
290 free( g_probes );
291 g_probes = 0;
292}
293
269static int add_task_to_kqueue( int kq, daemon_task * t_in ) { 294static int add_task_to_kqueue( int kq, daemon_task * t_in ) {
270 struct kevent ke; 295 struct kevent ke;
271 daemon_task * t; 296 daemon_task * t;
272 pid_t pid; 297 pid_t pid;
298 size_t i;
273 299
274 if( check_for_jail( t_in->m_jid ) ) { 300 if( check_for_jail( t_in->m_jid ) ) {
275 syslog( LOG_ERR, "Invalid jail id: %d", t_in->m_jid ); 301 syslog( LOG_ERR, "Invalid jail id: %d", t_in->m_jid );
@@ -297,6 +323,27 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) {
297 /* Expect reply from fork slave */ 323 /* Expect reply from fork slave */
298 pid = *(pid_t*)g_ipc_packet; 324 pid = *(pid_t*)g_ipc_packet;
299 325
326 /* Account for new pid */
327 for( i = 0; i < g_probes_size; ++i )
328 if( !g_probes[i] )
329 g_probes[i] = pid;
330
331 /* No space for pid entry => make room */
332 if( i == g_probes_size ) {
333 size_t bytes = sizeof(pid_t) * g_probes_size;
334 pid_t *probes = realloc( g_probes, 4 * bytes );
335 /* If we can not allocate memory, just ignore. Worst case is a defunct
336 probe process in the jail once the daemon dies. Probably the probe
337 will be killed anyway when the kevent below fails, too. */
338 if( probes ) {
339 /* Erase new memory */
340 memset( probes + g_probes_size, 0, 3 * bytes );
341 probes[g_probes_size] = pid;
342 g_probes_size *= 4;
343 g_probes = probes;
344 }
345 }
346
300 /* Associate pid with command line to execute and add to our kqueue */ 347 /* Associate pid with command line to execute and add to our kqueue */
301 memset( &ke, 0, sizeof ke ); 348 memset( &ke, 0, sizeof ke );
302 EV_SET( &ke, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, t ); 349 EV_SET( &ke, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, t );
@@ -320,7 +367,7 @@ int main( int argc, char **argv ) {
320 int o_force_daemon = 0; 367 int o_force_daemon = 0;
321 int o_daemonize = 0, o_jid = -1, o_respawn = 0; 368 int o_daemonize = 0, o_jid = -1, o_respawn = 0;
322 char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL; 369 char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL;
323 char *o_uds_path = "/var/run/jaildaemon"; 370 char *o_uds_path = "/var/run/jaildaemon.pipe";
324 struct kevent ke; 371 struct kevent ke;
325 struct sockaddr_un addr; 372 struct sockaddr_un addr;
326 struct sigaction sa; 373 struct sigaction sa;
@@ -447,11 +494,16 @@ int main( int argc, char **argv ) {
447 /* We do not care for the spawned process -- it is checked for in our 494 /* We do not care for the spawned process -- it is checked for in our
448 kqueue filter. So just ignore SIGCHLD */ 495 kqueue filter. So just ignore SIGCHLD */
449 memset( &sa, 0, sizeof( sa ) ); 496 memset( &sa, 0, sizeof( sa ) );
450 sigemptyset(&sa.sa_mask);
451 sa.sa_flags = SA_NOCLDWAIT; 497 sa.sa_flags = SA_NOCLDWAIT;
452 if( sigaction(SIGCHLD, &sa, NULL) == -1 ) 498 if( sigaction(SIGCHLD, &sa, NULL) == -1 )
453 exerr( "when trying to enable auto reap" ); 499 exerr( "when trying to enable auto reap" );
454 500
501 /* When dying gracefully, this signal handler sends TERM signals to all
502 probes */
503 sa.sa_handler = term_handler;
504 if( sigaction(SIGTERM, &sa, NULL) == -1 )
505 exerr( "when trying to install TERM handler" );
506
455 /* Create our kqueue */ 507 /* Create our kqueue */
456 if( ( kq = kqueue( ) ) == -1 ) 508 if( ( kq = kqueue( ) ) == -1 )
457 exerr( "when create kqueue" ); 509 exerr( "when create kqueue" );
@@ -466,10 +518,18 @@ int main( int argc, char **argv ) {
466 kevent( kq, &ke, 1, NULL, 0, NULL ); 518 kevent( kq, &ke, 1, NULL, 0, NULL );
467 519
468 /* We want to be notified if the fork slave died. This is a good time to 520 /* We want to be notified if the fork slave died. This is a good time to
469 die, too*/ 521 die, too */
470 EV_SET( &ke, g_fork_slave_fd, EVFILT_READ, EV_ADD, 0, 0, 0); 522 EV_SET( &ke, g_fork_slave_fd, EVFILT_READ, EV_ADD, 0, 0, 0);
471 kevent( kq, &ke, 1, NULL, 0, NULL ); 523 kevent( kq, &ke, 1, NULL, 0, NULL );
472 524
525 /* Prepare probe pids list, initally 128 processes long, vector grows by
526 factor 4, when exhausted */
527 g_probes = malloc( sizeof(pid_t) * PROBES_VECTOR_SIZE );
528 g_probes_size = PROBES_VECTOR_SIZE;
529 if( !g_probes )
530 exerr( "allocating memory." );
531 memset( g_probes, 0, sizeof(pid_t) * PROBES_VECTOR_SIZE );
532 atexit( kill_all_probes );
473 533
474 /* If daemon was started with some initial script, fire it now 534 /* If daemon was started with some initial script, fire it now
475 -- this leaks some information in the command line to all jails and 535 -- this leaks some information in the command line to all jails and
@@ -502,6 +562,7 @@ int main( int argc, char **argv ) {
502 switch( ke.filter ) { 562 switch( ke.filter ) {
503 case EVFILT_PROC: 563 case EVFILT_PROC:
504 if( ke.fflags & NOTE_EXIT ) { 564 if( ke.fflags & NOTE_EXIT ) {
565 size_t i;
505 daemon_task * task = (daemon_task *)ke.udata; 566 daemon_task * task = (daemon_task *)ke.udata;
506 if( !task ) 567 if( !task )
507 continue; 568 continue;
@@ -525,6 +586,11 @@ int main( int argc, char **argv ) {
525 EV_SET( &ke, ke.ident, EVFILT_PROC, EV_DELETE, NOTE_EXIT, 586 EV_SET( &ke, ke.ident, EVFILT_PROC, EV_DELETE, NOTE_EXIT,
526 0, NULL ); 587 0, NULL );
527 kevent( kq, &ke, 1, NULL, 0, NULL ); 588 kevent( kq, &ke, 1, NULL, 0, NULL );
589
590 /* Remove pid from our probes list */
591 for( i = 0; i < g_probes_size; ++i )
592 if( g_probes[i] == (pid_t)ke.ident )
593 g_probes[i] = 0;
528 } 594 }
529 break; 595 break;
530 case EVFILT_READ: 596 case EVFILT_READ: