From 2e02e531588c28bf907b9676c8e8d085771f2ea6 Mon Sep 17 00:00:00 2001 From: Stefan Grundmann Date: Wed, 31 May 2017 22:55:00 +0000 Subject: introduce -g switch; because -u alone will not work if security.bsd.see_other_gids=0 --- jaildaemon.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/jaildaemon.c b/jaildaemon.c index 46e14af..089b16e 100644 --- a/jaildaemon.c +++ b/jaildaemon.c @@ -44,6 +44,7 @@ typedef struct { int m_jid; int m_flags; uid_t m_uid; + gid_t m_gid; char *m_commandline; char *m_proctitle; } daemon_task; @@ -55,7 +56,7 @@ static void remove_files( void ); static int check_for_jail( int jid ); static int copy_daemontask( daemon_task ** out, daemon_task * const in ); static int add_task_to_kqueue( int kq, daemon_task * task_in ); -static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ); +static pid_t fork_and_jail( int jid, uid_t uid, gid_t gid, char * proctitle ); static void fork_and_execve( int kq, daemon_task * task ); static int fork_fork_slave( ); static void exerr( char * message, ... ); @@ -95,7 +96,7 @@ static void exerr( char * message, ... ) { static void usage( char * cmd ) { fprintf( stderr, "%s -D [-p pidfile] [-f ipcsockpath]\n" - "%s -c command -j jid [-t proctitle] [-rR] [-u uid]" + "%s -c command -j jid [-t proctitle] [-rR] [-u uid] [-g gid]" " [-f ipcsockpath]\n", cmd, cmd ); exit( 1 ); @@ -130,7 +131,8 @@ static void fork_slave( int master_fd ) { /* Decode packet and throw a forked child */ *(pid_t*)g_ipc_packet = fork_and_jail( g_ipc_packet_int[0], (uid_t)g_ipc_packet_int[1], - g_ipc_packet + 2 * sizeof(int) ); + (gid_t)g_ipc_packet_int[2], + g_ipc_packet + 3 * sizeof(int) ); if( write( master_fd, g_ipc_packet, sizeof(pid_t) ) != sizeof(pid_t) ) exerr( "Error: Can not reply to master." ); @@ -196,7 +198,7 @@ static int check_for_jail( int jid ) { return -1; } -static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ) { +static pid_t fork_and_jail( int jid, uid_t uid, gid_t gid, char * proctitle ) { int sig; pid_t pid = fork(); if( !pid ) { @@ -213,6 +215,7 @@ static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ) { exerr( "Error: Can not attach process to jail %d.", jid ); /* If we're supposed to drop privileges, do it now */ + setgid( gid ); setuid( uid ); /* wait for SIGHUP */ @@ -235,6 +238,7 @@ static int copy_daemontask( daemon_task ** out, daemon_task * const in ) { t->m_jid = in->m_jid; t->m_flags = in->m_flags; t->m_uid = in->m_uid; + t->m_gid = in->m_gid; t->m_commandline = in->m_commandline ? strdup( in->m_commandline ): 0; t->m_proctitle = in->m_proctitle ? strdup( in->m_proctitle ) : 0; @@ -342,9 +346,10 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) { memset( g_ipc_packet, 0, IPC_PACKETSIZE ); g_ipc_packet_int[0] = t->m_jid; g_ipc_packet_int[1] = t->m_uid; + g_ipc_packet_int[2] = t->m_gid; if( t->m_proctitle ) - strncpy( g_ipc_packet + 2 * sizeof(int), t->m_proctitle, - IPC_PACKETSIZE - 2 * sizeof(int) ); + strncpy( g_ipc_packet + 3 * sizeof(int), t->m_proctitle, + IPC_PACKETSIZE - 3 * sizeof(int) ); if( write( g_fork_slave_fd, g_ipc_packet, IPC_PACKETSIZE ) != IPC_PACKETSIZE ) exerr( "Error: Can not send task to fork slave." ); @@ -402,7 +407,8 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) { } /* jaildaemon -D [-ppidfile] [-fipcsockpath] - jaildaemon -c command -j jid [-t proctitle] [-rR] [-u uid] [-fipsockpath] + jaildaemon -c command -j jid [-t proctitle] [-rR] [-u uid] [-g gid] + [-fipsockpath] */ int main( int argc, char **argv ) { pid_t second_pid; @@ -411,6 +417,7 @@ int main( int argc, char **argv ) { int o_daemonize = 0, o_jid = -1, o_respawn = TASK_SINGLESHOT; char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL; uid_t o_uid = 0; + gid_t o_gid = 0; struct kevent ke; struct sockaddr_un addr; struct sigaction sa; @@ -423,7 +430,7 @@ int main( int argc, char **argv ) { i=1; while(i) { - switch( getopt( argc, argv, "DFrRt:c:j:p:u:f:" ) ) { + switch( getopt( argc, argv, "DFrRt:c:j:p:u:g:f:" ) ) { case -1: i=0; break; case 'D': o_daemonize = 1; break; case 'r': o_respawn = TASK_RESPAWN; break; @@ -432,6 +439,7 @@ int main( int argc, char **argv ) { case 'c': o_command = optarg; break; case 'j': o_jid = jail_getid(optarg); break; case 'u': o_uid = strtol( optarg, 0, 0 ); break; + case 'g': o_gid = strtol( optarg, 0, 0 ); break; case 'p': o_pidfile = optarg; break; case 'f': g_uds_path = optarg; break; case 'F': o_force_daemon = 1; break; @@ -463,6 +471,7 @@ int main( int argc, char **argv ) { int m_flags: SINGLESHOT, RESPAWN, RESPAWN_IMMEDIATE, RESPAWNING int m_jid int m_uid + int m_gid int m_commandline_length int m_proctitle_length char[] command_line \0 @@ -470,7 +479,7 @@ int main( int argc, char **argv ) { */ size_t o_command_len = strlen(o_command); size_t o_proctitle_len = o_proctitle ? strlen( o_proctitle ) : 0; - char *text_off = (char*)(g_ipc_packet_int + 5); + char *text_off = (char*)(g_ipc_packet_int + 6); if( text_off + 2 + o_command_len + o_proctitle_len > g_ipc_packet + IPC_PACKETSIZE ) @@ -479,8 +488,9 @@ int main( int argc, char **argv ) { g_ipc_packet_int[0] = o_respawn; g_ipc_packet_int[1] = o_jid; g_ipc_packet_int[2] = o_uid; - g_ipc_packet_int[3] = o_command_len; - g_ipc_packet_int[4] = o_proctitle_len; + g_ipc_packet_int[3] = o_gid; + g_ipc_packet_int[4] = o_command_len; + g_ipc_packet_int[5] = o_proctitle_len; memcpy( text_off, o_command, o_command_len + 1 ); if( o_proctitle_len ) { text_off += o_command_len + 1; @@ -640,7 +650,7 @@ int main( int argc, char **argv ) { break; case EVFILT_READ: if( (int)ke.ident == g_uds ) { - char *text_off = (char*)(g_ipc_packet_int + 5); + char *text_off = (char*)(g_ipc_packet_int + 6); socklen_t fromlen; daemon_task task; @@ -659,8 +669,9 @@ int main( int argc, char **argv ) { task.m_flags = g_ipc_packet_int[0]; task.m_jid = g_ipc_packet_int[1]; task.m_uid = g_ipc_packet_int[2]; + task.m_gid = g_ipc_packet_int[3]; task.m_commandline = text_off; - text_off += g_ipc_packet_int[3]; + text_off += g_ipc_packet_int[4]; /* Sanity check on string length, expect terminator */ if( text_off > (char *)( g_ipc_packet + IPC_PACKETSIZE ) || -- cgit v1.2.3