Fix output token and GSS context leaks in TKEY/GSS-API error paths

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.
This commit is contained in:
Ondřej Surý 2026-04-10 12:51:31 +02:00 committed by Michał Kępień
parent f14fac5a33
commit 1083ef3027
No known key found for this signature in database
2 changed files with 13 additions and 14 deletions

View 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);
}

View 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;
}