[krbdev.mit.edu #3498] race opening/creating replay cache.

Roland C. Dowdeswell via RT rt-comment at krbdev.mit.edu
Tue Mar 7 15:38:30 EST 2006


There is a race condition in the creation of the a replay cache,
or the replacement of a corrupt cache.  Basically, libraries when
opening a rcache do the following logic:

	1.  They try to open the file.

		a.  if the open succeeds

			i.   if the magic number matches, return success

			ii.  if not, unlink(2) the file.

	2.  They try to create the file with O_CREAT|O_EXCL.

	3.  They write the magic number in it.

Of course, if you have 2 processes doing this there is room for:

	There exists a time t s.t. both processes complete (1) before t
	and start (2) after t.

In this case, one of them will fail if either the file did not exist or
was malformed---i.e. had the wrong magic number in it.

This can be reproduced by running the following program:

/* $Id$ */

#include <stdio.h>
#include <string.h>

#include <krb5.h>

#define PRINC_NAME	"race"

#define K5BAIL(x)	do {					\
		code = (x);					\
		if (code) {					\
			fprintf(stderr, "%s: %s\n", #x,		\
			    error_message(code));		\
			exit(EXIT_FAILURE);			\
		}						\
	} while(0)

/*ARGSUSED*/
int
main(int argc, char **argv)
{       
	krb5_context	ctx;
	krb5_error_code	code;
	krb5_rcache	rcache;
	krb5_data	piece;

	piece.data = strdup(PRINC_NAME);
	piece.length = strlen(piece.data);

	K5BAIL(krb5_init_context(&ctx));
	K5BAIL(krb5_get_server_rcache(ctx, &piece, &rcache));

	return 0;
}

To reproduce:

	1.  Run it under gdb(1), set a break point in krb5_rc_io_open(),

	2.  Step until you unlink the file,

	3.  Run another copy of the program,

	4.  continue the first one, and

	5.  Note that it fails.  With the rather unhelpful error
	    ``permission denied''.

--
    Roland Dowdeswell                      http://www.Imrryr.ORG/~elric/




More information about the krb5-bugs mailing list