]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
rlm_kafka: unbox async opaques with talloc_get_type_abort
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 22 Apr 2026 16:38:33 +0000 (12:38 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Wed, 22 Apr 2026 16:38:33 +0000 (12:38 -0400)
xctx->inst / xctx->thread / msg->_private are all void pointers that
we know at the call-site should point back at our typed talloc chunks.
Using talloc_get_type_abort turns a subtle type-system hole into a
loud abort at the exact callsite if the opaque ever gets crossed over,
instead of a mystery crash deep in the function body.

The DR callback keeps its NULL-guard first - a NULL opaque is the
documented signal for fire-and-forget produces, so it's part of the
contract, not an error worth asserting on.

src/modules/rlm_kafka/rlm_kafka.c

index 998abc4b1513b8d749eb52192be1e4fc6c3c063b..7b8d3c91a82ae83658fb13f408fcffc9a51346e2 100644 (file)
@@ -596,7 +596,7 @@ typedef struct {
  */
 static int kafka_xlat_instantiate(xlat_inst_ctx_t const *xctx)
 {
-       rlm_kafka_xlat_inst_t   *inst = xctx->inst;
+       rlm_kafka_xlat_inst_t   *inst = talloc_get_type_abort(xctx->inst, rlm_kafka_xlat_inst_t);
        rlm_kafka_t const       *mod_inst = talloc_get_type_abort_const(xctx->mctx->mi->data, rlm_kafka_t);
        xlat_exp_t              *topic_arg;
        xlat_exp_t const        *topic_node;
@@ -654,8 +654,8 @@ static int kafka_xlat_instantiate(xlat_inst_ctx_t const *xctx)
  */
 static int kafka_xlat_thread_instantiate(xlat_thread_inst_ctx_t const *xctx)
 {
-       rlm_kafka_xlat_inst_t const     *inst = xctx->inst;
-       rlm_kafka_xlat_thread_inst_t    *t_inst = xctx->thread;
+       rlm_kafka_xlat_inst_t const     *inst = talloc_get_type_abort_const(xctx->inst, rlm_kafka_xlat_inst_t);
+       rlm_kafka_xlat_thread_inst_t    *t_inst = talloc_get_type_abort(xctx->thread, rlm_kafka_xlat_thread_inst_t);
        rlm_kafka_thread_t              *t;
 
        /*
@@ -789,9 +789,15 @@ static xlat_action_t kafka_xlat_produce(UNUSED TALLOC_CTX *xctx_ctx, UNUSED fr_d
  */
 static void _kafka_delivery_report_cb(UNUSED rd_kafka_t *rk, rd_kafka_message_t const *msg, UNUSED void *opaque)
 {
-       rlm_kafka_msg_ctx_t     *pctx = msg->_private;
+       rlm_kafka_msg_ctx_t     *pctx;
 
-       if (!pctx) return;
+       /*
+        *      A NULL opaque is the documented signal for
+        *      fire-and-forget produces - nothing to resume or free,
+        *      just return before we try to unbox the pointer.
+        */
+       if (!msg->_private) return;
+       pctx = talloc_get_type_abort(msg->_private, rlm_kafka_msg_ctx_t);
 
        fr_dlist_remove(&pctx->t->inflight, pctx);