]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib: Fix rundown of jobs sent with background_job_send()
authorVolker Lendecke <vl@samba.org>
Tue, 30 Mar 2021 15:18:10 +0000 (17:18 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 1 Apr 2021 19:32:36 +0000 (19:32 +0000)
When using this with a trigger message in smbd it will crash at
rundown in messaging_deregister because the global messaging context
can be TALLOC_FREE'ed before the background job is freed.

Using messaging_filtered_send already takes care of this situation
properly.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/lib/background.c

index 3c8eb5897cd90bf94dc913b13fb87c481b791550..74f7496d4f60594b533fc2ebad86ed9193ea8bf0 100644 (file)
@@ -40,9 +40,8 @@ struct background_job_state {
 static int background_job_state_destructor(struct background_job_state *s);
 static void background_job_waited(struct tevent_req *subreq);
 static void background_job_done(struct tevent_req *subreq);
-static void background_job_trigger(
-       struct messaging_context *msg, void *private_data, uint32_t msg_type,
-       struct server_id server_id, DATA_BLOB *data);
+static bool background_job_trigger(
+       struct messaging_rec *rec, void *private_data);
 
 struct tevent_req *background_job_send(TALLOC_CTX *mem_ctx,
                                       struct tevent_context *ev,
@@ -83,10 +82,9 @@ struct tevent_req *background_job_send(TALLOC_CTX *mem_ctx,
        talloc_set_destructor(state, background_job_state_destructor);
 
        for (i=0; i<num_trigger_msgs; i++) {
-               NTSTATUS status;
-               status = messaging_register(msg, state, trigger_msgs[i],
-                                           background_job_trigger);
-               if (tevent_req_nterror(req, status)) {
+               subreq = messaging_filtered_read_send(
+                       state, ev, msg, background_job_trigger, state);
+               if (tevent_req_nomem(subreq, req)) {
                        return tevent_req_post(req, ev);
                }
        }
@@ -103,36 +101,38 @@ struct tevent_req *background_job_send(TALLOC_CTX *mem_ctx,
 
 static int background_job_state_destructor(struct background_job_state *state)
 {
-       size_t i;
-
        TALLOC_FREE(state->pipe_req);
        if (state->pipe_fd != -1) {
                close(state->pipe_fd);
                state->pipe_fd = -1;
        }
 
-       for (i=0; i<state->num_trigger_msgs; i++) {
-               messaging_deregister(state->msg, state->trigger_msgs[i],
-                                    state);
-       }
-
        return 0;
 }
 
-static void background_job_trigger(
-       struct messaging_context *msg, void *private_data, uint32_t msg_type,
-       struct server_id server_id, DATA_BLOB *data)
+static bool background_job_trigger(
+       struct messaging_rec *rec, void *private_data)
 {
        struct background_job_state *state = talloc_get_type_abort(
                private_data, struct background_job_state);
+       size_t i;
 
        if (state->wakeup_req == NULL) {
-               return;
+               return false;
+       }
+       for (i=0; i<state->num_trigger_msgs; i++) {
+               if (rec->msg_type == state->trigger_msgs[i]) {
+                       break;
+               }
+       }
+       if (i == state->num_trigger_msgs) {
+               return false;
        }
        if (!tevent_req_set_endtime(state->wakeup_req, state->ev,
                                    timeval_zero())) {
                DEBUG(10, ("tevent_req_set_endtime failed\n"));
        }
+       return false;
 }
 
 static void background_job_waited(struct tevent_req *subreq)