diff -rup xinetd-2.3.14-orig/xinetd/child.c xinetd-2.3.14/xinetd/child.c --- xinetd-2.3.14-orig/xinetd/child.c 2006-11-28 14:03:07.000000000 -0500 +++ xinetd-2.3.14/xinetd/child.c 2006-11-29 17:04:19.000000000 -0500 @@ -33,6 +33,8 @@ #endif #ifdef LABELED_NET #include <selinux/selinux.h> +#include <selinux/flask.h> +#include <selinux/context.h> #endif #include "str.h" @@ -49,7 +51,7 @@ /* Local declarations */ #ifdef LABELED_NET -static int set_context_from_socket( int fd ); +static int set_context_from_socket( const struct service_config *scp, int fd ); #endif @@ -158,7 +160,7 @@ void exec_server( const struct server *s #ifdef LABELED_NET if (SC_LABELED_NET(scp)) { - if (set_context_from_socket( descriptor ) < 0) { + if (set_context_from_socket( scp, descriptor ) < 0) { msg( LOG_ERR, func, "Changing process context failed for %s", SC_ID( scp )) ; _exit( 1 ) ; @@ -485,16 +487,11 @@ void child_exit(void) } #ifdef LABELED_NET -static int set_context_from_socket( int fd ) +static int set_context( security_context_t cntx ) { - const char *func = "set_context_from_socket" ; - security_context_t peer_context; + const char *func = "set_context" ; - if (getpeercon(fd, &peer_context) < 0) - return -1; - - int retval = setexeccon(peer_context); - freecon( peer_context ); + int retval = setexeccon(cntx); if (debug.on) { @@ -513,4 +510,59 @@ static int set_context_from_socket( int return retval; } + +static int set_context_from_socket( const struct service_config *scp, int fd ) +{ + security_context_t curr_context = NULL; + security_context_t peer_context = NULL; + security_context_t exec_context = NULL; + context_t bcon = NULL; + context_t pcon = NULL; + security_context_t new_context = NULL; + security_context_t new_exec_context = NULL; + int retval = -1; + const char *exepath = NULL; + + if (getcon(&curr_context) < 0) + goto fail; + + if (getpeercon(fd, &peer_context) < 0) + goto fail; + + exepath = SC_SERVER( scp ); + if (getfilecon(exepath, &exec_context) < 0) + goto fail; + + if (!(bcon = context_new(curr_context))) + goto fail; + + if (!(pcon = context_new(peer_context))) + goto fail; + + if (!context_range_get(pcon)) + goto fail; + + if (context_range_set(bcon, context_range_get(pcon))) + goto fail; + + if (!(new_context = context_str(bcon))) + goto fail; + + if (security_compute_create(new_context, exec_context, SECCLASS_PROCESS, + &new_exec_context) < 0) + goto fail; + + retval = set_context(new_exec_context); + + freecon(new_exec_context); + + fail: + context_free(pcon); + context_free(bcon); + freecon(exec_context); + freecon(peer_context); + freecon(curr_context); + + return retval; +} #endif