]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Fix defcred leak in krb5 gss_inquire_cred() 1202/head
authorGreg Hudson <ghudson@mit.edu>
Fri, 16 Jul 2021 17:39:39 +0000 (13:39 -0400)
committerGreg Hudson <ghudson@mit.edu>
Wed, 21 Jul 2021 15:50:46 +0000 (11:50 -0400)
Commit 1cd2821c19b2b95e39d5fc2f451a035585a40fa5 altered the memory
management of krb5_gss_inquire_cred(), introducing defcred to act as
an owner pointer when the function must acquire a default credential.
The commit neglected to update the code to release the default cred
along the successful path.  The old code does not trigger because
cred_handle is now reassigned, so the default credential is leaked.

Unify the success and failure cleanup for this function so that
defcred is properly released on success.

Reported by Pavel Březina.

ticket: 9016
tags: pullup
target_version: 1.19-next
target_version: 1.18-next

src/lib/gssapi/krb5/inq_cred.c

index a8f2541102e7cfe661d0ec4718a685bc775b4d88..bb63b726c885dec18c440f5daa440715e7b15c51 100644 (file)
@@ -127,7 +127,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
     if ((code = krb5_timeofday(context, &now))) {
         *minor_status = code;
         ret = GSS_S_FAILURE;
-        goto fail;
+        goto cleanup;
     }
 
     if (cred->expire != 0) {
@@ -158,7 +158,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
             *minor_status = code;
             save_error_info(*minor_status, context);
             ret = GSS_S_FAILURE;
-            goto fail;
+            goto cleanup;
         }
     }
 
@@ -174,7 +174,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
             if (ret_name)
                 kg_release_name(context, &ret_name);
             /* *minor_status set above */
-            goto fail;
+            goto cleanup;
         }
     }
 
@@ -190,20 +190,16 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
 
     if (cred_usage)
         *cred_usage = cred->usage;
-    k5_mutex_unlock(&cred->lock);
 
     if (mechanisms) {
         *mechanisms = mechs;
         mechs = GSS_C_NO_OID_SET;
     }
 
-    if (cred_handle == GSS_C_NO_CREDENTIAL)
-        krb5_gss_release_cred(minor_status, (gss_cred_id_t *)&cred);
-
-    krb5_free_context(context);
     *minor_status = 0;
-    return((lifetime == 0)?GSS_S_CREDENTIALS_EXPIRED:GSS_S_COMPLETE);
-fail:
+    ret = (lifetime == 0) ? GSS_S_CREDENTIALS_EXPIRED : GSS_S_COMPLETE;
+
+cleanup:
     k5_mutex_unlock(&cred->lock);
     krb5_gss_release_cred(&tmpmin, &defcred);
     krb5_free_context(context);