[4463] in Kerberos

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

"krb5_rc_io_move" does the unexpected

daemon@ATHENA.MIT.EDU (Jim Miller)
Mon Jan 9 18:08:05 1995

From: jim@bilbo.suite.com (Jim Miller)
Date: Mon, 9 Jan 95 16:45:27 -0600
To: krb5-bugs@MIT.EDU
Cc: kerberos@MIT.EDU
Reply-To: Jim_Miller@suite.com



This bug report is for KRB5, beta 4, patchlevel 3.

The function "krb5_rc_io_move" does something it shouldn't.  Here's the  
code:

krb5_error_code krb5_rc_io_move (new, old)
krb5_rc_iostuff *new;
krb5_rc_iostuff *old;
{
 if (rename(old->fn,new->fn) == -1) /* MUST be atomic! */
   return KRB5_RC_IO_UNKNOWN;
 (void) krb5_rc_io_close(new);  <- ** frees new->fn
 new->fn = old->fn;             <- ** new's original fn is lost
 new->fd = old->fd;
 return 0;
}


Currently, the only place that "krb5_rc_io_move" is called is at the end  
of "krb5_rc_dfl_expunge".  In this case, "new" is the rcache you're trying  
to expunge and "old" is the temporary rcache with a funny temporary name.   
The intent of the call to "krb5_rc_io_move" is to rename the expunged tmp  
rcache to the same name as the original un-expunged rcache, wiping out the  
original file.  The wipe out happens as planned, but a side effect is that  
the "new" rcache struct (which is supposed to be the origianal rcache) is  
given "tmp's" funny temporary file name.  "new's" original name is lost.

This screws up "krb5_rc_destroy" because it tries to unlink the file named  
in the rcache struct, but because of "krb5_rc_io_move", the name is the  
funny temporary file name which doesn't exist anymore (it got renamed).

Solution:

"krb5_rc_io_move" needs to preserve the name held in "new->fn".  Something  
like the following should do the trick:

-------------------------------------------------

krb5_error_code krb5_rc_io_move (new, old)
krb5_rc_iostuff *new;
krb5_rc_iostuff *old;
{
 char *tmp_fn;
 

 if (rename(old->fn,new->fn) == -1) /* MUST be atomic! */
   return KRB5_RC_IO_UNKNOWN;

 tmp_fn = new->fn;
 new->fn = 0;                   /* zero to prevent freeing */
 

 (void) krb5_rc_io_close(new);  /* modified to check for 0 fn */

 new->fn = tmp_fn;              /* preserve original fn */
 new->fd = old->fd;

 return 0;
}

-------------------------------------------------

krb5_error_code krb5_rc_io_close (d)
krb5_rc_iostuff *d;
{
 if (d->fn) {           <- *** new: only frees if non-NULL
   FREE(d->fn);
   d->fn = NULL;
 }
 if (close(d->fd) == -1) /* can't happen */
   return KRB5_RC_IO_UNKNOWN;
 return 0;
}

-------------------------------------------------


Jim_Miller@suite.com


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