From c5ac1117b5509a136aae235adc31828ac092d29f Mon Sep 17 00:00:00 2001 From: Ezra Peisach Date: Thu, 1 Jun 2006 03:18:19 +0000 Subject: [PATCH] krb5 1.5 alpha - memory leaks in krb5kdc due to not freeing error messages In the kdc and lib/kadm5/logger.c, krb5_get_error_message needs to be paired with krb5_free_error_message to release returned memory. Essentially a memory leak was introduced for every principal requested that did not exist in the database. Identified by valgrind on the kdc - running kdc_hammer and specifying more principals than are present in the db. ticket: new tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@18072 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/do_as_req.c | 17 +++++++++++++++-- src/kdc/do_tgs_req.c | 23 +++++++++++++++++++---- src/kdc/kdc_preauth.c | 10 ++++++---- src/lib/kadm5/logger.c | 5 ++++- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 1523d1f80..6355e4bde 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -428,23 +428,36 @@ process_as_req(krb5_kdc_req *request, const krb5_fulladdr *from, errout: if (status) { + char * emsg = 0; + if (errcode) + emsg = krb5_get_error_message (kdc_context, errcode); + krb5_klog_syslog(LOG_INFO, "AS_REQ (%s) %s: %s: %s for %s%s%s", ktypestr, fromstring, status, cname ? cname : "", sname ? sname : "", errcode ? ", " : "", - errcode ? krb5_get_error_message (kdc_context, errcode) : ""); + errcode ? emsg : ""); + if (errcode) + krb5_free_error_message (kdc_context, emsg); } if (errcode) { - if (status == 0) + int got_err = 0; + if (status == 0) { status = krb5_get_error_message (kdc_context, errcode); + got_err = 1; + } errcode -= ERROR_TABLE_BASE_krb5; if (errcode < 0 || errcode > 128) errcode = KRB_ERR_GENERIC; errcode = prepare_error_as(request, errcode, &e_data, response, status); + if (got_err) { + krb5_free_error_message (kdc_context, status); + status = 0; + } } if (encrypting_key.contents) diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index 7f8f265a8..4f02ad60b 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -502,14 +502,17 @@ tgt_again: sname ? sname : "", enc_tkt_reply.transited.tr_contents.length, enc_tkt_reply.transited.tr_contents.data); - else + else { + char *emsg = krb5_get_error_message(kdc_context, errcode); krb5_klog_syslog (LOG_ERR, "unexpected error checking transit from '%s' to '%s' via '%.*s': %s", cname ? cname : "", sname ? sname : "", enc_tkt_reply.transited.tr_contents.length, enc_tkt_reply.transited.tr_contents.data, - krb5_get_error_message(kdc_context, errcode)); + emsg); + krb5_free_error_message(kdc_context, emsg); + } } else krb5_klog_syslog (LOG_INFO, "not checking transit path"); if (reject_bad_transit @@ -645,6 +648,9 @@ cleanup: if (status) { if (!errcode) rep_etypes2str(rep_etypestr, sizeof(rep_etypestr), &reply); + char * emsg = NULL; + if(errcode) + emsg = krb5_get_error_message (kdc_context, errcode); krb5_klog_syslog(LOG_INFO, "TGS_REQ (%s) %s: %s: authtime %d, " "%s%s %s for %s%s%s", @@ -655,18 +661,27 @@ cleanup: cname ? cname : "", sname ? sname : "", errcode ? ", " : "", - errcode ? krb5_get_error_message (kdc_context, errcode) : ""); + errcode ? emsg : ""); + if(errcode) + krb5_free_error_message (kdc_context, emsg); } if (errcode) { - if (status == 0) + int got_err = 0; + if (status == 0) { status = krb5_get_error_message (kdc_context, errcode); + got_err = 1; + } errcode -= ERROR_TABLE_BASE_krb5; if (errcode < 0 || errcode > 128) errcode = KRB_ERR_GENERIC; retval = prepare_error_tgs(request, header_ticket, errcode, fromstring, response, status); + if (got_err) { + krb5_free_error_message (kdc_context, status); + status = 0; + } } if (header_ticket) diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c index 48a6a6a7c..cd74528ad 100644 --- a/src/kdc/kdc_preauth.c +++ b/src/kdc/kdc_preauth.c @@ -370,9 +370,10 @@ check_padata (krb5_context context, krb5_db_entry *client, retval = pa_sys->verify_padata(context, client, request, enc_tkt_reply, *padata); if (retval) { + char * emsg = krb5_get_error_message (context, retval); krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s", - pa_sys->name, - krb5_get_error_message (context, retval)); + pa_sys->name, emsg); + krb5_free_error_message (context, emsg); if (pa_sys->flags & PA_REQUIRED) { pa_ok = 0; break; @@ -396,8 +397,9 @@ check_padata (krb5_context context, krb5_db_entry *client, return 0; if (!pa_found) { - krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s", - krb5_get_error_message(context, retval)); + char *emsg = krb5_get_error_message(context, retval); + krb5_klog_syslog (LOG_INFO, "no valid preauth type found: %s", emsg); + krb5_free_error_message(context, emsg); } /* The following switch statement allows us * to return some preauth system errors back to the client. diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c index f78c7b48e..24d845162 100644 --- a/src/lib/kadm5/logger.c +++ b/src/lib/kadm5/logger.c @@ -194,10 +194,13 @@ klog_com_err_proc(const char *whoami, long int code, const char *format, va_list /* If reporting an error message, separate it. */ if (code) { + char *emsg; outbuf[sizeof(outbuf) - 1] = '\0'; - strncat(outbuf, krb5_get_error_message (err_context, code), sizeof(outbuf) - 1 - strlen(outbuf)); + emsg = krb5_get_error_message (err_context, code); + strncat(outbuf, emsg, sizeof(outbuf) - 1 - strlen(outbuf)); strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf)); + krb5_free_error_message(err_context, emsg); } cp = &outbuf[strlen(outbuf)]; -- 2.26.2