krb5 1.5 alpha - memory leaks in krb5kdc due to not freeing error messages
authorEzra Peisach <epeisach@mit.edu>
Thu, 1 Jun 2006 03:18:19 +0000 (03:18 +0000)
committerEzra Peisach <epeisach@mit.edu>
Thu, 1 Jun 2006 03:18:19 +0000 (03:18 +0000)
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
src/kdc/do_tgs_req.c
src/kdc/kdc_preauth.c
src/lib/kadm5/logger.c

index 1523d1f80e53b7b7ffc4d27312b65010962f41f0..6355e4bde41ae1c9e183521e3cdb4cfaf07cd60a 100644 (file)
@@ -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 : "<unknown client>",
               sname ? sname : "<unknown server>",
               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)
index 7f8f265a8ec30402af21aeba543425c339a44f2c..4f02ad60b435b2c9161add818089cb61d60a1687 100644 (file)
@@ -502,14 +502,17 @@ tgt_again:
                              sname ? sname : "<unknown server>",
                              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 : "<unknown client>",
                              sname ? sname : "<unknown server>",
                              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 : "<unknown client>",
                         sname ? sname : "<unknown server>",
                         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)
index 48a6a6a7c543f0e85ef2665b787efa5eb03a28fa..cd74528adfeee058c51b071542fd49a0ec03414b 100644 (file)
@@ -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.
index f78c7b48ebbe431a78b26431abb2fa71b3a8882c..24d845162be4da7332bd7137f10bd683da3265c7 100644 (file)
@@ -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)];