[3049] in Kerberos-V5-bugs

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

pending/699: [papowell@astart.com] Kerberos 5, please forward

daemon@ATHENA.MIT.EDU (Mike Whitson)
Mon Mar 8 21:20:07 1999

Resent-From: gnats@rt-11.MIT.EDU (GNATS Management)
Resent-To: gnats-admin@rt-11.MIT.EDU
Resent-Reply-To: krb5-bugs@MIT.EDU, Mike Whitson <mwhitson@MIT.EDU>
Date: 08 Mar 1999 21:19:31 -0500
From: Mike Whitson <mwhitson@MIT.EDU>
To: krb5-bugs@MIT.EDU


>Number:         699
>Category:       pending
>Synopsis:       [papowell@astart.com] Kerberos 5, please forward
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin
>State:          open
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Mon Mar 08 21:20:00 EST 1999
>Last-Modified:
>Originator:
>Organization:
>Release:
>Environment:
>Description:
>How-To-Repeat:
>Fix:
>Audit-Trail:
>Unformatted:
------- Start of forwarded message -------
Date: Mon, 8 Mar 1999 17:52:19 -0800 (PST)
From: papowell@astart.com
Message-Id: <199903090152.RAA15439@astart4.astart.com>
To: mwhitson@MIT.EDU
Subject: Kerberos 5, please forward

I seem to have misfiled/misplaced the email message you
sent to me about the folks working on Kerberos 5.  Apparently some bugs
are still in the Kerberos 5 library, especially in the routines
that I use.

File: ./lib/krb5/krb/sendauth.c

Problem:  wrong value being returned on function exit.
Problem:  dead (unreferenced) malloced() values are not freed on exit.

Original code, approximately line 213:
	retval = 0;     /* Normal return */
    if (out_creds) {
        *out_creds = credsp;
    }

out_creds is a pointer to where you want the credentials
returned.  At line 147 we have the code:

  
    if (!in_creds->ticket.length) {
        if ((retval = krb5_get_credentials(context, 0,
                           use_ccache, in_creds, &credsp)))
            goto error_return;
        credspout = credsp;             <<<<--- value to be returned 
    } else {
        credsp = in_creds;
    }   

So credspout is set to credsp,  saving credsp's value
so that later assignments to credsp does not change it and lose the
returned credentials in the process.

I think what you really want is:

    retval = 0;     /* Normal return */
    if (out_creds) {
        *out_creds = credspout;
    }


Now, if you cast your eye down a little further, you will discover
that you have:

  error_return:
      krb5_free_cred_contents(context, &creds);
      if (!out_creds && credspout)
*   krb5_free_creds(context, credspout);
*     if (!ccache && use_ccache)
*   krb5_cc_close(context, use_ccache);
      return(retval);
  }   


The lines marked with * have the interesting side effect of
freeing the credspout value,  which in the original code has
the sometimes disastrous effects of freeing the return value as well.

I believe that the correct code should be:
    
  error_return:
      krb5_free_cred_contents(context, &creds);
!     if(out_creds == 0) krb5_free_creds(context, credspout);
!     if (!ccache && use_ccache) krb5_cc_close(context, use_ccache);
      return(retval);
  }

Note that we now free creds - which is ok as it is not the credspout
value at this point.

If there is no out_creds value,  we free credspout,  eliminating a memory
leak.

Finally,  we free close and free up stuff if we are not caching it.

Here is a diff -c of the code.

Enjoy.


Patrick Powell                 Astart Technologies,
papowell@astart.com            9475 Chesapeake Drive, Suite D,
Network and System             San Diego, CA 92123
  Consulting                   619-874-6543 FAX 619-279-8424 
LPRng - Print Spooler (http://www.astart.com)


***************
*** 229,242 ****
    }
    retval = 0;     /* Normal return */
    if (out_creds) {
!       *out_creds = credspout;
    }

  error_return:
      krb5_free_cred_contents(context, &creds);
!     if(out_creds == 0) krb5_free_creds(context, credspout);
!     if (!ccache && use_ccache) krb5_cc_close(context, use_ccache);
      return(retval);
  }

! #endif
--- 213,228 ----
    }
    retval = 0;     /* Normal return */
    if (out_creds) {
!       *out_creds = credsp;
    }
    
  error_return:
      krb5_free_cred_contents(context, &creds);
!     if (!out_creds && credspout)
!   krb5_free_creds(context, credspout);
!     if (!ccache && use_ccache)
!   krb5_cc_close(context, use_ccache);
      return(retval);
  }   

------- End of forwarded message -------

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