[29587] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

krb5 commit: Fix GSSRPC server credential memory leak

daemon@ATHENA.MIT.EDU (Greg Hudson)
Thu Aug 25 10:31:08 2016

Date: Thu, 25 Aug 2016 10:31:03 -0400
From: Greg Hudson <ghudson@mit.edu>
Message-Id: <201608251431.u7PEV30w001952@drugstore.mit.edu>
To: cvs-krb5@mit.edu
Reply-To: krbdev@mit.edu
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

https://github.com/krb5/krb5/commit/670d9828086e979d5cdfd26f00ca88958a03754e
commit 670d9828086e979d5cdfd26f00ca88958a03754e
Author: Greg Hudson <ghudson@mit.edu>
Date:   Tue Aug 23 12:35:50 2016 -0400

    Fix GSSRPC server credential memory leak
    
    In svc_auth_gss.c, stop using the global svcauth_gss_creds, and
    instead keep a credential in struct svc_rpc_gss_data.  This change
    ensures that the same credential is used for each accept_sec_context
    call for a particular context, and ensures that the credential is
    freed when the authentication data is destroyed.  Also, do not acquire
    a credential when the default name is used (as it is in kadmind) as it
    is not needed.
    
    Leave the svcauth_gss_creds around for the backportable fix as it is
    in the library export list.  It will be removed in a subsequent
    commit.
    
    ticket: 8480 (new)
    target_version: 1.14-next
    target_version: 1.13-next

 src/lib/rpc/svc_auth_gss.c |   40 ++++++++++++++--------------------------
 1 files changed, 14 insertions(+), 26 deletions(-)

diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c
index b81c4a3..efd3e51 100644
--- a/src/lib/rpc/svc_auth_gss.c
+++ b/src/lib/rpc/svc_auth_gss.c
@@ -91,6 +91,7 @@ struct svc_auth_ops svc_auth_gss_ops = {
 
 struct svc_rpc_gss_data {
 	bool_t			established;	/* context established */
+	gss_cred_id_t		cred;		/* credential */
 	gss_ctx_id_t		ctx;		/* context id */
 	struct rpc_gss_sec	sec;		/* security triple */
 	gss_buffer_desc		cname;		/* GSS client name */
@@ -139,15 +140,23 @@ svcauth_gss_set_svc_name(gss_name_t name)
 }
 
 static bool_t
-svcauth_gss_acquire_cred(void)
+svcauth_gss_acquire_cred(struct svc_rpc_gss_data *gd)
 {
 	OM_uint32	maj_stat, min_stat;
 
 	log_debug("in svcauth_gss_acquire_cred()");
 
+	/* We don't need to acquire a credential if using the default name. */
+	if (svcauth_gss_name == GSS_C_NO_NAME)
+		return (TRUE);
+
+	/* Only acquire a credential once per authentication. */
+	if (gd->cred != GSS_C_NO_CREDENTIAL)
+		return (TRUE);
+
 	maj_stat = gss_acquire_cred(&min_stat, svcauth_gss_name, 0,
 				    GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
-				    &svcauth_gss_creds, NULL, NULL);
+				    &gd->cred, NULL, NULL);
 
 	if (maj_stat != GSS_S_COMPLETE) {
 		log_status("gss_acquire_cred", maj_stat, min_stat);
@@ -156,25 +165,6 @@ svcauth_gss_acquire_cred(void)
 	return (TRUE);
 }
 
-static bool_t
-svcauth_gss_release_cred(void)
-{
-	OM_uint32	maj_stat, min_stat;
-
-	log_debug("in svcauth_gss_release_cred()");
-
-	maj_stat = gss_release_cred(&min_stat, &svcauth_gss_creds);
-
-	if (maj_stat != GSS_S_COMPLETE) {
-		log_status("gss_release_cred", maj_stat, min_stat);
-		return (FALSE);
-	}
-
-	svcauth_gss_creds = NULL;
-
-	return (TRUE);
-}
-
 /* Invoke log_badauth callbacks for an authentication failure. */
 static void
 badauth(OM_uint32 maj, OM_uint32 minor, SVCXPRT *xprt)
@@ -210,7 +200,7 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
 
 	gr->gr_major = gss_accept_sec_context(&gr->gr_minor,
 					      &gd->ctx,
-					      svcauth_gss_creds,
+					      gd->cred,
 					      &recv_tok,
 					      GSS_C_NO_CHANNEL_BINDINGS,
 					      &gd->client_name,
@@ -494,7 +484,7 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
 		if (rqst->rq_proc != NULLPROC)
 			ret_freegc (AUTH_FAILED);		/* XXX ? */
 
-		if (!svcauth_gss_acquire_cred())
+		if (!svcauth_gss_acquire_cred(gd))
 			ret_freegc (AUTH_FAILED);
 
 		if (!svcauth_gss_accept_sec_context(rqst, &gr))
@@ -544,9 +534,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg,
 
 		log_debug("sendreply in destroy: %d", call_stat);
 
-		if (!svcauth_gss_release_cred())
-			ret_freegc (AUTH_FAILED);
-
 		SVCAUTH_DESTROY(rqst->rq_xprt->xp_auth);
 		rqst->rq_xprt->xp_auth = &svc_auth_none;
 
@@ -574,6 +561,7 @@ svcauth_gss_destroy(SVCAUTH *auth)
 	gd = SVCAUTH_PRIVATE(auth);
 
 	gss_delete_sec_context(&min_stat, &gd->ctx, GSS_C_NO_BUFFER);
+	gss_release_cred(&min_stat, &gd->cred);
 	gss_release_buffer(&min_stat, &gd->cname);
 	gss_release_buffer(&min_stat, &gd->checksum);
 
_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post