From krb5-bugs-incoming-bounces@PCH.mit.edu Fri Jun 16 14:30:12 2006 Received: from pch.mit.edu (PCH.MIT.EDU [18.7.21.90]) by krbdev.mit.edu (8.9.3p2) with ESMTP id OAA08780; Fri, 16 Jun 2006 14:30:12 -0400 (EDT) Received: from pch.mit.edu (pch.mit.edu [127.0.0.1]) by pch.mit.edu (8.13.6/8.12.8) with ESMTP id k5GITXiF019431 for ; Fri, 16 Jun 2006 14:29:33 -0400 Received: from pacific-carrier-annex.mit.edu (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.7.21.83]) by pch.mit.edu (8.13.6/8.12.8) with ESMTP id k5GGSewF030582 for ; Fri, 16 Jun 2006 12:28:40 -0400 Received: from skamandros.sncag.com ([217.111.56.2]) by pacific-carrier-annex.mit.edu (8.13.6/8.9.2) with ESMTP id k5GGScDq019319 for ; Fri, 16 Jun 2006 12:28:41 -0400 (EDT) Received: from skamandros.sncag.com (localhost [127.0.0.1]) by skamandros.sncag.com (8.13.4/8.13.4/Debian-3sarge1) with ESMTP id k5GGSbRl011428 for ; Fri, 16 Jun 2006 18:28:37 +0200 Received: (from rw@localhost) by skamandros.sncag.com (8.13.4/8.13.4/Submit) id k5GGSb35011425; Fri, 16 Jun 2006 18:28:37 +0200 Date: Fri, 16 Jun 2006 18:28:37 +0200 From: Rainer Weikusat Message-Id: <200606161628.k5GGSb35011425@skamandros.sncag.com> To: krb5-bugs@mit.edu Subject: new_connection (init_sec_context.c) memory leak X-send-pr-version: 3.99 X-Spam-Score: 0 X-Spam-Flag: NO X-Scanned-By: MIMEDefang 2.42 X-Mailman-Approved-At: Fri, 16 Jun 2006 14:29:32 -0400 X-BeenThere: krb5-bugs-incoming@mailman.mit.edu X-Mailman-Version: 2.1.6 Precedence: list Reply-To: rainer.weikusat@sncag.com Sender: krb5-bugs-incoming-bounces@PCH.mit.edu Errors-To: krb5-bugs-incoming-bounces@PCH.mit.edu >Submitter-Id: net >Originator: Rainer Weikusat >Organization: SNC AG >Confidential: no >Synopsis: new_connection routine in ../src/lib/gssapi/krb5/init_sec_context.c leaks memory >Severity: serious >Category: krb5-libs >Class: sw-bug >Release: 1.4.3 >Environment: System: Linux skamandros 2.6.16.18 #5 SMP Tue May 30 13:42:31 CEST 2006 i686 GNU/Linux Architecture: i686 >Description: The new_connection routine in ..src/lib/gssapi/krb5/init_sec_context.c calls the get_credentials routine from the same file (l. 538) which returns a dynamically allocated Kerberos credential via its output parameter k_cred if the call didn't fail. Afterwards, a couple of other tasks are done which all transfer to the fail: label in the same routine in case of a failure (eg because the Kerberos ticket has expired in the meantime). The failure code does not free the Kerberos credential returned by get_credentials, leading to a memory leak. >How-To-Repeat: Cause the new connection routine to be called with a Kerberos ticket to use that will expire 'shortly'. If the ticket is not already expired by the time get_credentials uses it, but expires before new_connection uses it (via make_ap_req_v1), the memory will be leaked. >Fix: --- kerberos-new-conn-leak/src/lib/gssapi/krb5/init_sec_context.c 19 Mar 2006 14:41:59 -0000 1.1.1.1 +++ kerberos-new-conn-leak/src/lib/gssapi/krb5/init_sec_context.c 16 Jun 2006 16:15:16 -0000 1.1.1.1.8.3 @@ -547,39 +547,46 @@ if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used) != GSS_S_COMPLETE) { code = *minor_status; - goto fail; - } - /* - * Now try to make it static if at all possible.... - */ - ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used); - - { - /* gsskrb5 v1 */ - krb5_ui_4 seq_temp; - if ((code = make_ap_req_v1(context, ctx, - cred, k_cred, input_chan_bindings, - mech_type, &token))) { - if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || - (code == KG_EMPTY_CCACHE)) - major_status = GSS_S_NO_CRED; - if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) - major_status = GSS_S_CREDENTIALS_EXPIRED; - goto fail; - } - - krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &seq_temp); - ctx->seq_send = seq_temp; - krb5_auth_con_getsendsubkey(context, ctx->auth_context, - &ctx->subkey); + } else { + /* + * Now try to make it static if at all possible.... + */ + ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used); + + { + /* gsskrb5 v1 */ + krb5_ui_4 seq_temp; + code = make_ap_req_v1(context, ctx, cred, k_cred, input_chan_bindings, + mech_type, &token); + switch (code) { + case 0: + krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, &seq_temp); + ctx->seq_send = seq_temp; + krb5_auth_con_getsendsubkey(context, ctx->auth_context, + &ctx->subkey); + + major_status = setup_enc(minor_status, ctx, context); + if (major_status) code = *minor_status; + break; + + case KRB5_FCC_NOFILE: + case KRB5_CC_NOTFOUND: + case KG_EMPTY_CCACHE: + major_status = GSS_S_NO_CRED; + break; + + case KRB5KRB_AP_ERR_TKT_EXPIRED: + major_status = GSS_S_CREDENTIALS_EXPIRED; + } + } } - major_status = setup_enc(minor_status, ctx, context); - if (k_cred) { krb5_free_creds(context, k_cred); k_cred = 0; } + + if (code) goto fail; /* at this point, the context is constructed and valid, hence, releaseable */