From: Volker Lendecke Date: Tue, 18 May 2021 06:32:45 +0000 (+0200) Subject: ctdb: Fix a crash in run_proc_signal_handler() X-Git-Tag: tevent-0.11.0~861 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=adef87a621b17baf746d12f991c60a8a3ffcfcd3;p=thirdparty%2Fsamba.git ctdb: Fix a crash in run_proc_signal_handler() If a script times out the caller can talloc_free() the script_list output of run_event_recv, which talloc_free's proc->output from run_proc.c as well. If the script generates further output after the timeout and then exits after a while, the SIGCHLD handler in the eventd tries to read into proc->output, which was already free'ed. Fix this by not doing just a talloc_steal but a talloc_move. This way proc_read_handler() called from run_proc_signal_handler() does not try to realloc the stale reference to proc->output but gets a NULL reference. I don't really know how to do a knownfail in ctdb, so this commit actually activates catching the signal by waiting long enough for 22.bar to exit and generate the SIGCHLD. Bug: https://bugzilla.samba.org/show_bug.cgi?id=14475 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/ctdb/common/run_proc.c b/ctdb/common/run_proc.c index 0c3c1de72fe..d55af6c3a1e 100644 --- a/ctdb/common/run_proc.c +++ b/ctdb/common/run_proc.c @@ -426,7 +426,7 @@ static void run_proc_done(struct tevent_req *req) state->result = state->proc->result; if (state->proc->output != NULL) { - state->output = talloc_steal(state, state->proc->output); + state->output = talloc_move(state, &state->proc->output); } talloc_steal(state, state->proc); @@ -464,7 +464,7 @@ static void run_proc_timedout(struct tevent_req *subreq) state->result.err = ETIMEDOUT; if (state->proc->output != NULL) { - state->output = talloc_steal(state, state->proc->output); + state->output = talloc_move(state, &state->proc->output); } state->pid = state->proc->pid; @@ -495,7 +495,7 @@ bool run_proc_recv(struct tevent_req *req, int *perr, } if (output != NULL) { - *output = talloc_steal(mem_ctx, state->output); + *output = talloc_move(mem_ctx, &state->output); } return true; diff --git a/ctdb/tests/src/run_event_test.c b/ctdb/tests/src/run_event_test.c index 08e8b95e13d..94548647014 100644 --- a/ctdb/tests/src/run_event_test.c +++ b/ctdb/tests/src/run_event_test.c @@ -131,7 +131,7 @@ static void do_run(TALLOC_CTX *mem_ctx, struct tevent_context *ev, } req = tevent_wakeup_send( - ev, ev, tevent_timeval_current_ofs(1, 0)); + ev, ev, tevent_timeval_current_ofs(10, 0)); if (req == NULL) { fprintf(stderr, "Could not wait for signal\n"); return;