From 79b3ec305a1cbc6ac2f78a18f44730b15ba5e943 Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Thu, 9 Jun 2011 21:08:34 +0000 Subject: [PATCH] pull up r24722 from trunk ------------------------------------------------------------------------ r24722 | ghudson | 2011-03-17 16:02:01 -0400 (Thu, 17 Mar 2011) | 11 lines ticket: 6884 subject: KDC memory leak in FAST error path target_version: 1.9.1 tags: pullup When kdc_fast_handle_error() produces a FAST-encoded error, it puts it into err->e_data and it never gets freed (since in the non-FAST case, err->e_data contains aliased pointers). Fix this by storing the encoded error in an output variable which is placed into the error's e_data by the caller and then freed. ticket: 6884 version_fixed: 1.9.2 status: resolved git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-9@24949 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/do_as_req.c | 10 +++++++--- src/kdc/do_tgs_req.c | 11 ++++++++--- src/kdc/fast_util.c | 19 ++++++------------- src/kdc/kdc_util.h | 3 ++- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 464cb6e44..31057df23 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -689,7 +689,7 @@ prepare_error_as (struct kdc_request_state *rstate, krb5_kdc_req *request, { krb5_error errpkt; krb5_error_code retval; - krb5_data *scratch; + krb5_data *scratch, *fast_edata = NULL; krb5_pa_data **pa = NULL; krb5_typed_data **td = NULL; size_t size; @@ -748,9 +748,12 @@ prepare_error_as (struct kdc_request_state *rstate, krb5_kdc_req *request, } } retval = kdc_fast_handle_error(kdc_context, rstate, - request, pa, &errpkt); - if (retval == 0) + request, pa, &errpkt, &fast_edata); + if (retval == 0) { + if (fast_edata != NULL) + errpkt.e_data = *fast_edata; retval = krb5_mk_error(kdc_context, &errpkt, scratch); + } free(errpkt.text.data); if (retval) @@ -758,6 +761,7 @@ prepare_error_as (struct kdc_request_state *rstate, krb5_kdc_req *request, else *response = scratch; krb5_free_pa_data(kdc_context, pa); + krb5_free_data(kdc_context, fast_edata); return retval; } diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index b424b3edd..c169c54a9 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -991,7 +991,7 @@ prepare_error_tgs (struct kdc_request_state *state, { krb5_error errpkt; krb5_error_code retval = 0; - krb5_data *scratch; + krb5_data *scratch, *fast_edata = NULL; errpkt.ctime = request->nonce; errpkt.cusec = 0; @@ -1014,15 +1014,20 @@ prepare_error_tgs (struct kdc_request_state *state, return ENOMEM; } errpkt.e_data = *e_data; - if (state) - retval = kdc_fast_handle_error(kdc_context, state, request, NULL, &errpkt); + if (state) { + retval = kdc_fast_handle_error(kdc_context, state, request, NULL, + &errpkt, &fast_edata); + } if (retval) { free(scratch); free(errpkt.text.data); return retval; } + if (fast_edata) + errpkt.e_data = *fast_edata; retval = krb5_mk_error(kdc_context, &errpkt, scratch); free(errpkt.text.data); + krb5_free_data(kdc_context, fast_edata); if (retval) free(scratch); else diff --git a/src/kdc/fast_util.c b/src/kdc/fast_util.c index e411e320d..c460eb8f8 100644 --- a/src/kdc/fast_util.c +++ b/src/kdc/fast_util.c @@ -364,14 +364,15 @@ kdc_fast_response_handle_padata(struct kdc_request_state *state, /* * We assume the caller is responsible for passing us an in_padata * sufficient to include in a FAST error. In the FAST case we will - * throw away the e_data in the error (if any); in the non-FAST case - * we will not use the in_padata. + * set *fast_edata_out to the edata to be included in the error; in + * the non-FAST case we will set it to NULL. */ krb5_error_code kdc_fast_handle_error(krb5_context context, struct kdc_request_state *state, krb5_kdc_req *request, - krb5_pa_data **in_padata, krb5_error *err) + krb5_pa_data **in_padata, krb5_error *err, + krb5_data **fast_edata_out) { krb5_error_code retval = 0; krb5_fast_response resp; @@ -381,8 +382,8 @@ kdc_fast_handle_error(krb5_context context, krb5_pa_data *outer_pa[3], *cookie = NULL; krb5_pa_data **inner_pa = NULL; size_t size = 0; - krb5_data *encoded_e_data = NULL; + *fast_edata_out = NULL; memset(outer_pa, 0, sizeof(outer_pa)); if (!state || !state->armor_key) return 0; @@ -430,15 +431,7 @@ kdc_fast_handle_error(krb5_context context, pa[0].contents = (unsigned char *) encrypted_reply->data; outer_pa[0] = &pa[0]; } - retval = encode_krb5_padata_sequence(outer_pa, &encoded_e_data); - if (retval == 0) { - /*process_as holds onto a pointer to the original e_data and frees it*/ - err->e_data = *encoded_e_data; - free(encoded_e_data); /*contents belong to err*/ - encoded_e_data = NULL; - } - if (encoded_e_data) - krb5_free_data(kdc_context, encoded_e_data); + retval = encode_krb5_padata_sequence(outer_pa, fast_edata_out); if (encrypted_reply) krb5_free_data(kdc_context, encrypted_reply); if (encoded_fx_error) diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 998f29559..79137058b 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -355,7 +355,8 @@ krb5_error_code kdc_fast_handle_error (krb5_context context, struct kdc_request_state *state, krb5_kdc_req *request, - krb5_pa_data **in_padata, krb5_error *err); + krb5_pa_data **in_padata, krb5_error *err, + krb5_data **fast_edata_out); krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state, krb5_keyblock *existing_key, -- 2.26.2