From 2f88d95d8c72f1333ce1fc12a1ba18249447c11e Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Thu, 19 May 2016 17:24:51 +0200 Subject: [PATCH 1/2] AD: Do not leak file descriptors during machine password renewal Resolves: https://fedorahosted.org/sssd/ticket/3017 The AD renewal task was opening a pipe to write to the child process but never closed it, leaking the fd. This patch uses a desctructor we already use for pipes towards other child processes. --- src/providers/ad/ad_machine_pw_renewal.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c index b0d2cf64a59ca90982bc343a66bb3843f90610a3..205e623e0324ffac563a08ae8a08dd817aa4975f 100644 --- a/src/providers/ad/ad_machine_pw_renewal.c +++ b/src/providers/ad/ad_machine_pw_renewal.c @@ -101,8 +101,7 @@ struct renewal_state { struct tevent_timer *timeout_handler; struct tevent_context *ev; - int write_to_child_fd; - int read_from_child_fd; + struct child_io_fds *io; }; static void ad_machine_account_password_renewal_done(struct tevent_req *subreq); @@ -140,8 +139,15 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->child_status = EFAULT; - state->read_from_child_fd = -1; - state->write_to_child_fd = -1; + state->io = talloc(state, struct child_io_fds); + if (state->io == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); + ret = ENOMEM; + goto done; + } + state->io->write_to_child_fd = -1; + state->io->read_from_child_fd = -1; + talloc_set_destructor((void *) state->io, child_io_destructor); server_name = be_fo_get_active_server_name(be_ctx, AD_SERVICE_NAME); talloc_zfree(renewal_data->extra_args[0]); @@ -183,13 +189,13 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec renewal child\n"); } else if (child_pid > 0) { /* parent */ - state->read_from_child_fd = pipefd_from_child[0]; + state->io->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); - sss_fd_nonblocking(state->read_from_child_fd); + sss_fd_nonblocking(state->io->read_from_child_fd); - state->write_to_child_fd = pipefd_to_child[1]; + state->io->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); - sss_fd_nonblocking(state->write_to_child_fd); + sss_fd_nonblocking(state->io->write_to_child_fd); /* Set up SIGCHLD handler */ ret = child_handler_setup(ev, child_pid, NULL, NULL, &state->child_ctx); @@ -210,7 +216,7 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx, goto done; } - subreq = read_pipe_send(state, ev, state->read_from_child_fd); + subreq = read_pipe_send(state, ev, state->io->read_from_child_fd); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "read_pipe_send failed.\n"); ret = ERR_RENEWAL_CHILD; @@ -262,10 +268,6 @@ static void ad_machine_account_password_renewal_done(struct tevent_req *subreq) "---adcli output end---\n", (int) buf_len, buf); - close(state->read_from_child_fd); - state->read_from_child_fd = -1; - - tevent_req_done(req); return; } -- 2.4.11