ctdb: Fix a crash in run_proc_signal_handler()
authorVolker Lendecke <vl@samba.org>
Tue, 18 May 2021 06:32:45 +0000 (08:32 +0200)
committerKarolin Seeger <kseeger@samba.org>
Tue, 25 May 2021 08:55:59 +0000 (08:55 +0000)
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 <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit adef87a621b17baf746d12f991c60a8a3ffcfcd3)

Autobuild-User(v4-13-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-13-test): Tue May 25 08:55:59 UTC 2021 on sn-devel-184

ctdb/common/run_proc.c
ctdb/tests/src/run_event_test.c

index 0c3c1de72fe0144cd407136ff1d56ec96fb13746..d55af6c3a1e18293725728f51213fc66a0471b92 100644 (file)
@@ -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;
index 08e8b95e13d67c87c669a08162da848bea44bcb6..94548647014d289226b730da94cc85c1a7c76afc 100644 (file)
@@ -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;