From 298aea2c08823da7e05747a072dffbcd485491c8 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Thu, 10 May 2018 12:15:06 -0400 Subject: [PATCH] Prevent core dumps on intentional mons/tids subprocess abort() Uses setrlimit() to set the core size limit to 0 for the subprocess immediately before aborting. --- configure.ac | 2 +- mon/mons.c | 72 +++++++++++++++++++++++++++++++++++++++--------------------- tid/tids.c | 14 ++++++++---- 3 files changed, 58 insertions(+), 30 deletions(-) diff --git a/configure.ac b/configure.ac index 615a392..f688071 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.63) -AC_INIT([trust_router],[3.4.0~2], +AC_INIT([trust_router],[3.4.0~3], [bugs@project-moonshot.org]) AC_CONFIG_MACRO_DIR(m4) AC_CONFIG_AUX_DIR(build-aux) diff --git a/mon/mons.c b/mon/mons.c index cebe329..1d157af 100644 --- a/mon/mons.c +++ b/mon/mons.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "mons_handlers.h" @@ -214,6 +215,48 @@ int mons_get_listener(MONS_INSTANCE *mons, MONS_REQ_FUNC *req_handler, MONS_AUTH } /** + * Process to handle an incoming monitoring request + * + * This should be run in a child process after fork(). Handles the request + * and terminates. Never returns to the caller. + * + * @param mons the monitoring server instance + * @param conn_fd file descriptor for the incoming connection + */ +static void mons_handle_proc(MONS_INSTANCE *mons, int conn_fd) +{ + struct rlimit rlim; /* for disabling core dump */ + + switch(tr_gss_handle_connection(conn_fd, + "trustmonitor", mons->hostname, /* acceptor name */ + mons->auth_handler, mons->cookie, /* auth callback and cookie */ + mons_req_cb, mons /* req callback and cookie */ + )) { + case TR_GSS_SUCCESS: + /* do nothing */ + break; + + case TR_GSS_ERROR: + tr_debug("mons_accept: Error returned by tr_gss_handle_connection()"); + break; + + default: + tr_err("mons_accept: Unexpected value returned by tr_gss_handle_connection()"); + break; + } + close(conn_fd); + + /* This ought to be an exit(0), but log4shib does not play well with fork() due to + * threading issues. To ensure we do not get stuck in the exit handler, we will + * abort. First disable core dump for this subprocess (the main process will still + * dump core if the environment allows). */ + rlim.rlim_cur = 0; /* max core size of 0 */ + rlim.rlim_max = 0; /* prevent the core size limit from being raised later */ + setrlimit(RLIMIT_CORE, &rlim); + abort(); /* exit hard */ +} + +/** * Accept and process a connection on a port opened with mons_get_listener() * * @param mons monitoring interface instance @@ -236,34 +279,13 @@ int mons_accept(MONS_INSTANCE *mons, int listen) } if (pid == 0) { - close(listen); - switch(tr_gss_handle_connection(conn, - "trustmonitor", mons->hostname, /* acceptor name */ - mons->auth_handler, mons->cookie, /* auth callback and cookie */ - mons_req_cb, mons /* req callback and cookie */ - )) { - case TR_GSS_SUCCESS: - /* do nothing */ - break; - - case TR_GSS_ERROR: - tr_debug("mons_accept: Error returned by tr_gss_handle_connection()"); - break; - - default: - tr_err("mons_accept: Unexpected value returned by tr_gss_handle_connection()"); - break; - } - close(conn); - - /* This ought to be an exit(0), but log4shib does not play well with our (mis)use of threads and - * fork() in the main process. Until we sort that out, we abort() to force termination of this - * process. */ - abort(); /* exit hard */ + /* Only the child process gets here */ + close(listen); /* this belongs to the parent */ + mons_handle_proc(mons, conn); /* never returns */ } /* Only the parent process gets here */ - close(conn); + close(conn); /* this belongs to the child */ g_array_append_val(mons->pids, pid); /* clean up any processes that have completed */ diff --git a/tid/tids.c b/tid/tids.c index 1a29620..f6da08d 100644 --- a/tid/tids.c +++ b/tid/tids.c @@ -49,6 +49,7 @@ #include #include #include +#include /** * Create a response with minimal fields filled in @@ -408,7 +409,7 @@ nfds_t tids_get_listener(TIDS_INSTANCE *tids, * Process to handle an incoming TIDS request * * This should be run in the child process after a fork(). Handles - * the request, writes the result to result_fd, and terminates via exit(). + * the request, writes the result to result_fd, and terminates. * Never returns to the caller. * * @param tids TID server instance @@ -418,6 +419,7 @@ nfds_t tids_get_listener(TIDS_INSTANCE *tids, static void tids_handle_proc(TIDS_INSTANCE *tids, int conn_fd, int result_fd) { const char *response_message = NULL; + struct rlimit rlim; /* for disabling core dump */ switch(tr_gss_handle_connection(conn_fd, "trustidentity", tids->hostname, /* acceptor name */ @@ -443,9 +445,13 @@ static void tids_handle_proc(TIDS_INSTANCE *tids, int conn_fd, int result_fd) close(result_fd); close(conn_fd); - /* This ought to be an exit(0), but log4shib does not play well with our (mis)use of threads and - * fork() in the main process. Until we sort that out, we abort() to force termination of this - * process. */ + /* This ought to be an exit(0), but log4shib does not play well with fork() due to + * threading issues. To ensure we do not get stuck in the exit handler, we will + * abort. First disable core dump for this subprocess (the main process will still + * dump core if the environment allows). */ + rlim.rlim_cur = 0; /* max core size of 0 */ + rlim.rlim_max = 0; /* prevent the core size limit from being raised later */ + setrlimit(RLIMIT_CORE, &rlim); abort(); /* exit hard */ } -- 2.1.4