From 3171398867d22cc9c807a1574d7370cc2e906e8b Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Tue, 2 Jan 2024 13:46:43 +0000 Subject: [PATCH] krb5: Fix use-after-free when debug is enabled with http_proxy. Instead of freeing host->ai on return from submit_request in the http_proxy path, stash the proxy's ai in another member host->freeai which will be freed when host is freed. Assumption: All hosts created in submit_request cease to be used before any of them are freed, so it's safe to pick one host to hang the proxy's ai on and free the ai when that host is freed. fix https://github.com/heimdal/heimdal/issues/1205 --- lib/krb5/send_to_kdc.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/krb5/send_to_kdc.c b/lib/krb5/send_to_kdc.c index bcabdd4a1..5d8ec4215 100644 --- a/lib/krb5/send_to_kdc.c +++ b/lib/krb5/send_to_kdc.c @@ -328,6 +328,7 @@ struct host_fun { struct host { enum host_state { CONNECT, CONNECTING, CONNECTED, WAITING_REPLY, DEAD } state; krb5_krbhst_info *hi; + struct addrinfo *freeai; struct addrinfo *ai; rk_socket_t fd; const struct host_fun *fun; @@ -393,6 +394,9 @@ deallocate_host(void *ptr) if (!rk_IS_BAD_SOCKET(host->fd)) rk_closesocket(host->fd); krb5_data_free(&host->data); + if (host->freeai) + freeaddrinfo(host->freeai); + host->freeai = NULL; host->ai = NULL; } @@ -800,7 +804,7 @@ static krb5_error_code submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi) { unsigned long submitted_host = 0; - krb5_boolean freeai = FALSE; + struct addrinfo *freeai = NULL; struct timeval nrstart, nrstop; krb5_error_code ret; struct addrinfo *ai = NULL, *a; @@ -857,8 +861,8 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi) free(proxy2); if (ret) return krb5_eai_to_heim_errno(ret, errno); - - freeai = TRUE; + + freeai = ai; } else { ret = krb5_krbhst_get_addrinfo(context, hi, &ai); @@ -893,13 +897,15 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi) host = heim_alloc(sizeof(*host), "sendto-host", deallocate_host); if (host == NULL) { if (freeai) - freeaddrinfo(ai); + freeaddrinfo(freeai); rk_closesocket(fd); return ENOMEM; } host->hi = hi; host->fd = fd; host->ai = a; + host->freeai = freeai; + freeai = NULL; /* next version of stid */ host->tid = ctx->stid = (ctx->stid & 0xffff0000) | ((ctx->stid & 0xffff) + 1); @@ -946,7 +952,7 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi) } if (freeai) - freeaddrinfo(ai); + freeai = NULL; if (submitted_host == 0) return KRB5_KDC_UNREACH;