]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix output token and GSS context leaks in TKEY/GSS-API error paths
authorOndřej Surý <ondrej@isc.org>
Fri, 10 Apr 2026 10:51:31 +0000 (12:51 +0200)
committerMichał Kępień <michal@isc.org>
Thu, 7 May 2026 11:32:15 +0000 (13:32 +0200)
In dst_gssapi_acceptctx(), rename outtoken to outtokenp (matching BIND
convention for output pointer parameters) and free the allocated output
token buffer on error in the cleanup path.

In process_gsstkey(), route the empty-principal error path through
cleanup via CLEANUP() instead of returning early, so that the output
token, GSS context, and TSIG key are all freed consistently by the
existing cleanup block.

lib/dns/gssapictx.c
lib/dns/tkey.c

index bbfebb9accc8c2d1b67cb4295307a841554fac09..a2d55de3e0085deba6bc58744fe68b104e41db9e 100644 (file)
@@ -378,7 +378,7 @@ cleanup:
 
 isc_result_t
 dst_gssapi_acceptctx(const char *gssapi_keytab, isc_region_t *intoken,
-                    isc_buffer_t **outtoken, dns_gss_ctx_id_t *ctxout,
+                    isc_buffer_t **outtokenp, dns_gss_ctx_id_t *ctxout,
                     dns_name_t *principal, isc_mem_t *mctx) {
        isc_region_t r;
        isc_buffer_t namebuf;
@@ -390,7 +390,7 @@ dst_gssapi_acceptctx(const char *gssapi_keytab, isc_region_t *intoken,
        isc_result_t result;
        char buf[1024];
 
-       REQUIRE(outtoken != NULL && *outtoken == NULL);
+       REQUIRE(outtokenp != NULL && *outtokenp == NULL);
        REQUIRE(*ctxout == NULL);
 
        REGION_TO_GBUFFER(*intoken, gintoken);
@@ -470,10 +470,10 @@ dst_gssapi_acceptctx(const char *gssapi_keytab, isc_region_t *intoken,
        }
 
        if (gouttoken.length > 0U) {
-               isc_buffer_allocate(mctx, outtoken,
+               isc_buffer_allocate(mctx, outtokenp,
                                    (unsigned int)gouttoken.length);
                GBUFFER_TO_REGION(gouttoken, r);
-               CHECK(isc_buffer_copyregion(*outtoken, &r));
+               CHECK(isc_buffer_copyregion(*outtokenp, &r));
                (void)gss_release_buffer(&minor, &gouttoken);
        }
 
@@ -510,6 +510,10 @@ dst_gssapi_acceptctx(const char *gssapi_keytab, isc_region_t *intoken,
        *ctxout = context;
 
 cleanup:
+       if (result != ISC_R_SUCCESS && *outtokenp != NULL) {
+               isc_buffer_free(outtokenp);
+       }
+
        if (result != ISC_R_SUCCESS && context != GSS_C_NO_CONTEXT) {
                (void)gss_delete_sec_context(&minor, &context, NULL);
        }
index 38bdbd3ad74d9df64551945d2e0ba94d13c4c35a..b22fed78a42852c3ed32c9205a891edbdc9fcaeb 100644 (file)
@@ -182,12 +182,9 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin,
        result = dst_gssapi_acceptctx(tctx->gssapi_keytab, &intoken, &outtoken,
                                      &gss_ctx, principal, tctx->mctx);
        if (result != ISC_R_SUCCESS) {
-               if (tsigkey != NULL) {
-                       dns_tsigkey_detach(&tsigkey);
-               }
                tkeyout->error = dns_tsigerror_badkey;
                tkey_log("process_gsstkey(): dns_tsigerror_badkey");
-               return ISC_R_SUCCESS;
+               CLEANUP(ISC_R_SUCCESS);
        }
 
        /*
@@ -196,14 +193,10 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin,
         * negotiation is complete and the principal must be set.
         */
        if (dns_name_countlabels(principal) == 0U) {
-               if (tsigkey != NULL) {
-                       dns_tsigkey_detach(&tsigkey);
-               }
-               dst_gssapi_deletectx(tctx->mctx, &gss_ctx);
                tkeyout->error = dns_tsigerror_badkey;
                tkey_log("process_gsstkey(): "
                         "completed context with empty principal");
-               return ISC_R_SUCCESS;
+               CLEANUP(ISC_R_SUCCESS);
        } else if (tsigkey == NULL) {
 #if HAVE_GSSAPI
                OM_uint32 gret, minor, lifetime;
@@ -282,7 +275,9 @@ cleanup:
                isc_buffer_free(&outtoken);
        }
 
-       tkey_log("process_gsstkey(): %s", isc_result_totext(result));
+       if (result != ISC_R_SUCCESS) {
+               tkey_log("process_gsstkey(): %s", isc_result_totext(result));
+       }
        return result;
 }