From: Stefan Metzmacher Date: Sat, 19 May 2018 08:14:25 +0000 (+0200) Subject: s4:messaging: allow imessaging_post_handler() to free the messaging context from... X-Git-Tag: tdb-1.3.16~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a08ab2940051ae47ce71149087a24d060227ef19;p=thirdparty%2Fsamba.git s4:messaging: allow imessaging_post_handler() to free the messaging context from a handler In usecases like using messaging_client_init() with irpc processing we may free the imessaging_context during the messaging handler. imessaging_post_handler() is not yet really used, but it will change in the next commits. imessaging_post_state is a child of imessaging_context and might be implicitly free'ed before the explicit TALLOC_FREE(state). Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index b8d4e50f12c..8903322bdc7 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -433,18 +433,48 @@ fail: struct imessaging_post_state { struct imessaging_context *msg_ctx; + struct imessaging_post_state **busy_ref; size_t buf_len; uint8_t buf[]; }; +static int imessaging_post_state_destructor(struct imessaging_post_state *state) +{ + if (state->busy_ref != NULL) { + *state->busy_ref = NULL; + state->busy_ref = NULL; + } + return 0; +} + static void imessaging_post_handler(struct tevent_context *ev, struct tevent_immediate *ti, void *private_data) { struct imessaging_post_state *state = talloc_get_type_abort( private_data, struct imessaging_post_state); + + /* + * In usecases like using messaging_client_init() with irpc processing + * we may free the imessaging_context during the messaging handler. + * imessaging_post_state is a child of imessaging_context and + * might be implicitly free'ed before the explicit TALLOC_FREE(state). + * + * The busy_ref pointer makes sure the destructor clears + * the local 'state' variable. + */ + + SMB_ASSERT(state->busy_ref == NULL); + state->busy_ref = &state; + imessaging_dgm_recv(ev, state->buf, state->buf_len, NULL, 0, state->msg_ctx); + + if (state == NULL) { + return; + } + + state->busy_ref = NULL; TALLOC_FREE(state); } @@ -461,6 +491,8 @@ static int imessaging_post_self(struct imessaging_context *msg, } talloc_set_name_const(state, "struct imessaging_post_state"); + talloc_set_destructor(state, imessaging_post_state_destructor); + ti = tevent_create_immediate(state); if (ti == NULL) { TALLOC_FREE(state); @@ -468,6 +500,7 @@ static int imessaging_post_self(struct imessaging_context *msg, } state->msg_ctx = msg; + state->busy_ref = NULL; state->buf_len = buf_len; memcpy(state->buf, buf, buf_len);