diff options
author | erdgeist <> | 2013-03-28 18:29:47 +0000 |
---|---|---|
committer | erdgeist <> | 2013-03-28 18:29:47 +0000 |
commit | 28fcbc589634cf68e233cbfb407a1eb19db32bcd (patch) | |
tree | 94772f7aeee63ca0b7db742c4f8ed3ae4eb3fea5 | |
parent | 4bb364b6fa63bbf59ca5ffc55e898c45285379e4 (diff) |
Introduce -u switch to allow dropping the probes' uid to something non-root processes in the jail can send signals to
-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) || |