diff options
| -rw-r--r-- | jaildaemon.c | 45 | 
1 files changed, 29 insertions, 16 deletions
diff --git a/jaildaemon.c b/jaildaemon.c index a4e2d8d..62dcc51 100644 --- a/jaildaemon.c +++ b/jaildaemon.c  | |||
| @@ -42,6 +42,7 @@ static size_t g_probes_size; | |||
| 42 | typedef struct { | 42 | typedef struct { | 
| 43 | int m_jid; | 43 | int m_jid; | 
| 44 | int m_flags; | 44 | int m_flags; | 
| 45 | uid_t m_uid; | ||
| 45 | char *m_commandline; | 46 | char *m_commandline; | 
| 46 | char *m_proctitle; | 47 | char *m_proctitle; | 
| 47 | } daemon_task; | 48 | } daemon_task; | 
| @@ -53,7 +54,7 @@ static void remove_files( void ); | |||
| 53 | static int check_for_jail( int jid ); | 54 | static int check_for_jail( int jid ); | 
| 54 | static int copy_daemontask( daemon_task ** out, daemon_task * const in ); | 55 | static int copy_daemontask( daemon_task ** out, daemon_task * const in ); | 
| 55 | static int add_task_to_kqueue( int kq, daemon_task * task_in ); | 56 | static int add_task_to_kqueue( int kq, daemon_task * task_in ); | 
| 56 | static pid_t fork_and_jail( int jid, char * proctitle ); | 57 | static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ); | 
| 57 | static void fork_and_execve( int kq, daemon_task * task ); | 58 | static void fork_and_execve( int kq, daemon_task * task ); | 
| 58 | static int fork_fork_slave( ); | 59 | static int fork_fork_slave( ); | 
| 59 | static void exerr( char * message, ... ); | 60 | static void exerr( char * message, ... ); | 
| @@ -92,8 +93,9 @@ static void exerr( char * message, ... ) { | |||
| 92 | /* Report syntax of command line arguments to the user */ | 93 | /* Report syntax of command line arguments to the user */ | 
| 93 | static void usage( char * cmd ) { | 94 | static void usage( char * cmd ) { | 
| 94 | fprintf( stderr, | 95 | fprintf( stderr, | 
| 95 | "%s -D [-ppidfile] [-fipcsockpath]\n" | 96 | "%s -D [-p pidfile] [-f ipcsockpath]\n" | 
| 96 | "%s -c command -j jid [-t proctitle] [-rR] [-fipcsockpath]\n", | 97 | "%s -c command -j jid [-t proctitle] [-rR] [-u uid] -f ipcsockpath]" | 
| 98 | "\n", | ||
| 97 | cmd, cmd ); | 99 | cmd, cmd ); | 
| 98 | exit( 1 ); | 100 | exit( 1 ); | 
| 99 | } | 101 | } | 
| @@ -122,7 +124,8 @@ static void fork_slave( int master_fd ) { | |||
| 122 | case IPC_PACKETSIZE: | 124 | case IPC_PACKETSIZE: | 
| 123 | /* Decode packet and throw a forked child */ | 125 | /* Decode packet and throw a forked child */ | 
| 124 | *(pid_t*)g_ipc_packet = fork_and_jail( | 126 | *(pid_t*)g_ipc_packet = fork_and_jail( | 
| 125 | g_ipc_packet_int[0], g_ipc_packet + sizeof(int) ); | 127 | g_ipc_packet_int[0], (uid_t)g_ipc_packet_int[1], | 
| 128 | g_ipc_packet + 2 * sizeof(int) ); | ||
| 126 | if( write( master_fd, g_ipc_packet, sizeof(pid_t) ) != | 129 | if( write( master_fd, g_ipc_packet, sizeof(pid_t) ) != | 
| 127 | sizeof(pid_t) ) | 130 | sizeof(pid_t) ) | 
| 128 | exerr( "Error: Can not reply to master." ); | 131 | exerr( "Error: Can not reply to master." ); | 
| @@ -188,7 +191,7 @@ static int check_for_jail( int jid ) { | |||
| 188 | return -1; | 191 | return -1; | 
| 189 | } | 192 | } | 
| 190 | 193 | ||
| 191 | static pid_t fork_and_jail( int jid, char * proctitle ) { | 194 | static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ) { | 
| 192 | int sig; | 195 | int sig; | 
| 193 | pid_t pid = fork(); | 196 | pid_t pid = fork(); | 
| 194 | if( !pid ) { | 197 | if( !pid ) { | 
| @@ -204,6 +207,9 @@ static pid_t fork_and_jail( int jid, char * proctitle ) { | |||
| 204 | if( jail_attach( jid ) ) | 207 | if( jail_attach( jid ) ) | 
| 205 | exerr( "Error: Can not attach process to jail %d.", jid ); | 208 | exerr( "Error: Can not attach process to jail %d.", jid ); | 
| 206 | 209 | ||
| 210 | /* If we're supposed to drop privileges, do it now */ | ||
| 211 | setuid( uid ); | ||
| 212 | |||
| 207 | /* wait for SIGHUP */ | 213 | /* wait for SIGHUP */ | 
| 208 | sigemptyset(&sigset); | 214 | sigemptyset(&sigset); | 
| 209 | sigaddset(&sigset, SIGHUP); | 215 | sigaddset(&sigset, SIGHUP); | 
| @@ -223,6 +229,7 @@ static int copy_daemontask( daemon_task ** out, daemon_task * const in ) { | |||
| 223 | 229 | ||
| 224 | t->m_jid = in->m_jid; | 230 | t->m_jid = in->m_jid; | 
| 225 | t->m_flags = in->m_flags; | 231 | t->m_flags = in->m_flags; | 
| 232 | t->m_uid = in->m_uid; | ||
| 226 | t->m_commandline = in->m_commandline ? strdup( in->m_commandline ): 0; | 233 | t->m_commandline = in->m_commandline ? strdup( in->m_commandline ): 0; | 
| 227 | t->m_proctitle = in->m_proctitle ? strdup( in->m_proctitle ) : 0; | 234 | t->m_proctitle = in->m_proctitle ? strdup( in->m_proctitle ) : 0; | 
| 228 | 235 | ||
| @@ -329,9 +336,10 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) { | |||
| 329 | /* Forge a command packet for fork slave and send it via control socket */ | 336 | /* Forge a command packet for fork slave and send it via control socket */ | 
| 330 | memset( g_ipc_packet, 0, IPC_PACKETSIZE ); | 337 | memset( g_ipc_packet, 0, IPC_PACKETSIZE ); | 
| 331 | g_ipc_packet_int[0] = t->m_jid; | 338 | g_ipc_packet_int[0] = t->m_jid; | 
| 339 | g_ipc_packet_int[1] = t->m_uid; | ||
| 332 | if( t->m_proctitle ) | 340 | if( t->m_proctitle ) | 
| 333 | strncpy( g_ipc_packet + sizeof(int), t->m_proctitle, | 341 | strncpy( g_ipc_packet + 2 * sizeof(int), t->m_proctitle, | 
| 334 | IPC_PACKETSIZE - sizeof(int) ); | 342 | IPC_PACKETSIZE - 2 * sizeof(int) ); | 
| 335 | if( write( g_fork_slave_fd, g_ipc_packet, IPC_PACKETSIZE ) != | 343 | if( write( g_fork_slave_fd, g_ipc_packet, IPC_PACKETSIZE ) != | 
| 336 | IPC_PACKETSIZE ) | 344 | IPC_PACKETSIZE ) | 
| 337 | exerr( "Error: Can not send task to fork slave." ); | 345 | exerr( "Error: Can not send task to fork slave." ); | 
| @@ -389,7 +397,7 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) { | |||
| 389 | } | 397 | } | 
| 390 | 398 | ||
| 391 | /* jaildaemon -D [-ppidfile] [-fipcsockpath] | 399 | /* jaildaemon -D [-ppidfile] [-fipcsockpath] | 
| 392 | jaildaemon -c command -j jid -t proctitle [-rR] [-fipsockpath] | 400 | jaildaemon -c command -j jid [-t proctitle] [-rR] [-u uid] [-fipsockpath] | 
| 393 | */ | 401 | */ | 
| 394 | int main( int argc, char **argv ) { | 402 | int main( int argc, char **argv ) { | 
| 395 | pid_t second_pid; | 403 | pid_t second_pid; | 
| @@ -397,6 +405,7 @@ int main( int argc, char **argv ) { | |||
| 397 | int o_force_daemon = 0; | 405 | int o_force_daemon = 0; | 
| 398 | int o_daemonize = 0, o_jid = -1, o_respawn = TASK_SINGLESHOT; | 406 | int o_daemonize = 0, o_jid = -1, o_respawn = TASK_SINGLESHOT; | 
| 399 | char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL; | 407 | char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL; | 
| 408 | uid_t o_uid = 0; | ||
| 400 | struct kevent ke; | 409 | struct kevent ke; | 
| 401 | struct sockaddr_un addr; | 410 | struct sockaddr_un addr; | 
| 402 | struct sigaction sa; | 411 | struct sigaction sa; | 
| @@ -409,7 +418,7 @@ int main( int argc, char **argv ) { | |||
| 409 | 418 | ||
| 410 | i=1; | 419 | i=1; | 
| 411 | while(i) { | 420 | while(i) { | 
| 412 | switch( getopt( argc, argv, "DFrRt:c:j:p:f:" ) ) { | 421 | switch( getopt( argc, argv, "DFrRt:c:j:p:u:f:" ) ) { | 
| 413 | case -1: i=0; break; | 422 | case -1: i=0; break; | 
| 414 | case 'D': o_daemonize = 1; break; | 423 | case 'D': o_daemonize = 1; break; | 
| 415 | case 'r': o_respawn = TASK_RESPAWN; break; | 424 | case 'r': o_respawn = TASK_RESPAWN; break; | 
| @@ -417,6 +426,7 @@ int main( int argc, char **argv ) { | |||
| 417 | case 't': o_proctitle = optarg; break; | 426 | case 't': o_proctitle = optarg; break; | 
| 418 | case 'c': o_command = optarg; break; | 427 | case 'c': o_command = optarg; break; | 
| 419 | case 'j': o_jid = strtol( optarg, 0, 0 ); break; | 428 | case 'j': o_jid = strtol( optarg, 0, 0 ); break; | 
| 429 | case 'u': o_uid = strtol( optarg, 0, 0 ); break; | ||
| 420 | case 'p': o_pidfile = optarg; break; | 430 | case 'p': o_pidfile = optarg; break; | 
| 421 | case 'f': g_uds_path = optarg; break; | 431 | case 'f': g_uds_path = optarg; break; | 
| 422 | case 'F': o_force_daemon = 1; break; | 432 | case 'F': o_force_daemon = 1; break; | 
| @@ -447,6 +457,7 @@ int main( int argc, char **argv ) { | |||
| 447 | Packed packet format: | 457 | Packed packet format: | 
| 448 | int m_flags: SINGLESHOT, RESPAWN, RESPAWN_IMMEDIATE, RESPAWNING | 458 | int m_flags: SINGLESHOT, RESPAWN, RESPAWN_IMMEDIATE, RESPAWNING | 
| 449 | int m_jid | 459 | int m_jid | 
| 460 | int m_uid | ||
| 450 | int m_commandline_length | 461 | int m_commandline_length | 
| 451 | int m_proctitle_length | 462 | int m_proctitle_length | 
| 452 | char[] command_line \0 | 463 | char[] command_line \0 | 
| @@ -454,7 +465,7 @@ int main( int argc, char **argv ) { | |||
| 454 | */ | 465 | */ | 
| 455 | size_t o_command_len = strlen(o_command); | 466 | size_t o_command_len = strlen(o_command); | 
| 456 | size_t o_proctitle_len = o_proctitle ? strlen( o_proctitle ) : 0; | 467 | size_t o_proctitle_len = o_proctitle ? strlen( o_proctitle ) : 0; | 
| 457 | char *text_off = (char*)(g_ipc_packet_int + 4); | 468 | char *text_off = (char*)(g_ipc_packet_int + 5); | 
| 458 | 469 | ||
| 459 | if( text_off + 2 + o_command_len + o_proctitle_len > | 470 | if( text_off + 2 + o_command_len + o_proctitle_len > | 
| 460 | g_ipc_packet + IPC_PACKETSIZE ) | 471 | g_ipc_packet + IPC_PACKETSIZE ) | 
| @@ -462,8 +473,9 @@ int main( int argc, char **argv ) { | |||
| 462 | 473 | ||
| 463 | g_ipc_packet_int[0] = o_respawn; | 474 | g_ipc_packet_int[0] = o_respawn; | 
| 464 | g_ipc_packet_int[1] = o_jid; | 475 | g_ipc_packet_int[1] = o_jid; | 
| 465 | g_ipc_packet_int[2] = o_command_len; | 476 | g_ipc_packet_int[2] = o_uid; | 
| 466 | g_ipc_packet_int[3] = o_proctitle_len; | 477 | g_ipc_packet_int[3] = o_command_len; | 
| 478 | g_ipc_packet_int[4] = o_proctitle_len; | ||
| 467 | memcpy( text_off, o_command, o_command_len + 1 ); | 479 | memcpy( text_off, o_command, o_command_len + 1 ); | 
| 468 | if( o_proctitle_len ) { | 480 | if( o_proctitle_len ) { | 
| 469 | text_off += o_command_len + 1; | 481 | text_off += o_command_len + 1; | 
| @@ -623,7 +635,7 @@ int main( int argc, char **argv ) { | |||
| 623 | break; | 635 | break; | 
| 624 | case EVFILT_READ: | 636 | case EVFILT_READ: | 
| 625 | if( (int)ke.ident == g_uds ) { | 637 | if( (int)ke.ident == g_uds ) { | 
| 626 | char *text_off = (char*)(g_ipc_packet_int + 4); | 638 | char *text_off = (char*)(g_ipc_packet_int + 5); | 
| 627 | socklen_t fromlen; | 639 | socklen_t fromlen; | 
| 628 | daemon_task task; | 640 | daemon_task task; | 
| 629 | 641 | ||
| @@ -641,8 +653,9 @@ int main( int argc, char **argv ) { | |||
| 641 | 653 | ||
| 642 | task.m_flags = g_ipc_packet_int[0]; | 654 | task.m_flags = g_ipc_packet_int[0]; | 
| 643 | task.m_jid = g_ipc_packet_int[1]; | 655 | task.m_jid = g_ipc_packet_int[1]; | 
| 656 | task.m_uid = g_ipc_packet_int[2]; | ||
| 644 | task.m_commandline = text_off; | 657 | task.m_commandline = text_off; | 
| 645 | text_off += g_ipc_packet_int[2]; | 658 | text_off += g_ipc_packet_int[3]; | 
| 646 | 659 | ||
| 647 | /* Sanity check on string length, expect terminator */ | 660 | /* Sanity check on string length, expect terminator */ | 
| 648 | if( text_off > (char *)( g_ipc_packet + IPC_PACKETSIZE ) || | 661 | if( text_off > (char *)( g_ipc_packet + IPC_PACKETSIZE ) || | 
| @@ -651,8 +664,8 @@ int main( int argc, char **argv ) { | |||
| 651 | continue; | 664 | continue; | 
| 652 | } | 665 | } | 
| 653 | 666 | ||
| 654 | task.m_proctitle = g_ipc_packet_int[3] ? ++text_off : 0; | 667 | task.m_proctitle = g_ipc_packet_int[4] ? ++text_off : 0; | 
| 655 | text_off += g_ipc_packet_int[3]; | 668 | text_off += g_ipc_packet_int[4]; | 
| 656 | 669 | ||
| 657 | /* Sanity check on string length, expect terminator */ | 670 | /* Sanity check on string length, expect terminator */ | 
| 658 | if( text_off > (char *)(g_ipc_packet + IPC_PACKETSIZE) || | 671 | if( text_off > (char *)(g_ipc_packet + IPC_PACKETSIZE) || | 
