Patch 9/9: process_tgs_req() must release encrypting_key
Alexandr Nedvedicky
alexandr.nedvedicky at oracle.com
Mon Feb 19 19:47:10 EST 2018
Hello,
I'm upgrading kerberos bundled with Solaris to krb5-1.16. Solaris currently
ships krb5-1.15.1. I've noticed there are some memory leaks, while running test
suite, which comes with krb-1.16 (e.g. running 'make check'). I don't think
those memory leaks are critical, though as kerberos newbie I can't be sure, so
I think I'm better to share my findings. All memory leaks were found using
'libumem', which can be found on Solaris (or its OSS sibbling illumos).
All patches are against krb5-1.16 release.
There are two ways how db_tgs_req() obtains encrypting_key:
539 if (isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY)) {
540 krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
541 encrypting_key = *(t2enc->session);
542 } else {
543 /*
544 * Find the server key
545 */
546 if ((errcode = krb5_dbe_find_enctype(kdc_context, server,
547 -1, /* ignore keytype */
548 -1, /* Ignore salttype */
549 0, /* Get highest kvno */
550 &server_key))) {
551 status = "FINDING_SERVER_KEY";
552 goto cleanup;
553 }
554
555 /*
556 * Convert server.key into a real key
557 * (it may be encrypted in the database)
558 */
559 if ((errcode = krb5_dbe_decrypt_key_data(kdc_context, NULL,
560 server_key, &encrypting_key,
561 NULL))) {
562 status = "DECRYPT_SERVER_KEY";
563 goto cleanup;
564 }
it either reads it from request (lines 540-541) or gets it via call
to krb5_dbe_decrypt_key_data() at line 559. If function executes
line 559, then it must also make sure the encrypting_key is freed.
regards
sasha
--------8<---------------8<---------------8<------------------8<--------
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 293791814..b845e756b 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -114,6 +114,7 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
int newtransited = 0;
krb5_error_code retval = 0;
krb5_keyblock encrypting_key;
+ krb5_keyblock *cleanup_encrypting_key;
krb5_timestamp kdc_time, authtime = 0;
krb5_keyblock session_key;
krb5_keyblock *reply_key = NULL;
@@ -146,6 +147,7 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
memset(&enc_tkt_reply, 0, sizeof(enc_tkt_reply));
memset(&encrypting_key, 0, sizeof(krb5_keyblock));
memset(&session_key, 0, sizeof(krb5_keyblock));
+ cleanup_encrypting_key = NULL;
retval = decode_krb5_tgs_req(pkt, &request);
if (retval)
@@ -554,13 +556,13 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
* Convert server.key into a real key
* (it may be encrypted in the database)
*/
- memset(&encrypting_key, 0, sizeof (encrypting_key));
if ((errcode = krb5_dbe_decrypt_key_data(kdc_context, NULL,
server_key, &encrypting_key,
NULL))) {
status = "DECRYPT_SERVER_KEY";
goto cleanup;
}
+ cleanup_encrypting_key = &encrypting_key;
}
if (isflagset(c_flags, KRB5_KDB_FLAG_CONSTRAINED_DELEGATION)) {
@@ -879,6 +881,10 @@ cleanup:
krb5_free_pa_data(kdc_context, reply_encpart.enc_padata);
if (enc_tkt_reply.authorization_data != NULL)
krb5_free_authdata(kdc_context, enc_tkt_reply.authorization_data);
+ if (cleanup_encrypting_key != NULL) {
+ free(cleanup_encrypting_key->contents);
+ cleanup_encrypting_key->contents = NULL;
+ }
krb5_free_pa_data(kdc_context, e_data);
k5_free_data_ptr_list(auth_indicators);
More information about the krbdev
mailing list