Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: binary MIME-Version: 1.0 X-Mailer: MIME-tools 5.411 (Entity 5.404) X-RT-Original-Encoding: iso-8859-1 Content-Length: 6009 From kenh@cmf.nrl.navy.mil Sun Nov 10 23:17:01 1996 Received: from MIT.EDU (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.69.0.28]) by rt-11.MIT.EDU (8.7.5/8.7.3) with SMTP id XAA17641 for ; Sun, 10 Nov 1996 23:17:01 -0500 Received: from [134.207.10.161] by MIT.EDU with SMTP id AA06477; Sun, 10 Nov 96 23:16:47 EST Received: from nexus.cmf.nrl.navy.mil (kenh@nexus.cmf.nrl.navy.mil [134.207.10.9]) by ginger.cmf.nrl.navy.mil (8.7.5/8.7.3) with ESMTP id XAA13625 for ; Sun, 10 Nov 1996 23:16:49 -0500 (EST) Received: (kenh@localhost) by nexus.cmf.nrl.navy.mil (8.7.5/8.6.11) id XAA16344; Sun, 10 Nov 1996 23:16:44 -0500 (EST) Message-Id: <199611110416.XAA16344@nexus.cmf.nrl.navy.mil> Date: Sun, 10 Nov 1996 23:16:44 -0500 (EST) From: Ken Hornstein Reply-To: kenh@cmf.nrl.navy.mil To: krb5-bugs@MIT.EDU Subject: Fix for infinitely growing replay cache X-Send-Pr-Version: 3.2 >Number: 174 >Category: krb5-libs >Synopsis: A fix for the problem where the reply cache grows without bounds >Confidential: no >Severity: critical >Priority: high >Responsible: krb5-unassigned >State: closed >Class: sw-bug >Submitter-Id: unknown >Arrival-Date: Sun Nov 10 23:18:00 EST 1996 >Last-Modified: Mon Nov 18 22:29:12 EST 1996 >Originator: Ken Hornstein >Organization: Naval Research Lab >Release: beta-7 >Environment: System: SunOS nexus 4.1.4 1 sun4m Architecture: sun4 >Description: The replay cache code automatically prunes the replay cache if too many entries are in a hash bucket. This works great for long-living daemons like the KDC. However, for daemons that start up once, do one authentication, then exit, the replay cache will grow without bounds. Eventually noticable delays will incur as each invokation of the daemon requires it to read in the entire replay cache. >How-To-Repeat: Retrieve your mail via KPOP, and notice over a period of time that it keeps taking longer and longer ... >Fix: This is a rework of the patch that Jonathan Kamens posted a little while back. His patch was for beta 4 (I think) -- this is done up for beta 7. I've been running with this for a couple of weeks now with no ill effects. I just wanted to resend this so anyone who needed a fix could put it in place now. --- lib/krb5/rcache/rc_dfl.c.orig Mon Nov 27 15:51:53 1995 +++ lib/krb5/rcache/rc_dfl.c Wed Oct 23 15:19:34 1996 @@ -54,7 +54,11 @@ of live krb5_donot_replays by EXCESSREPS. With the defaults here, a typical cache might build up some 10K of expired krb5_donot_replays before an automatic expunge, with the waste basically independent of the number of stores per -minute. */ +minute. + +The rcache will also automatically be expunged when it encounters more +than EXCESSREPS expired entries when recovering a cache in +dfl_recover. */ static int hash(rep, hsize) krb5_donot_replay *rep; @@ -110,6 +114,7 @@ #ifndef NOIOSTUFF krb5_rc_iostuff d; #endif + char recovering; } ; @@ -281,6 +286,7 @@ #ifndef NOIOSTUFF t->d.fd = -1; #endif + t->recovering = 0; return 0; cleanup: @@ -388,12 +394,15 @@ #else struct dfl_data *t = (struct dfl_data *)id->data; - krb5_donot_replay *rep; + krb5_donot_replay *rep = 0; krb5_error_code retval; long max_size; + int expired_entries = 0; if ((retval = krb5_rc_io_open(context, &t->d, t->name))) return retval; + + t->recovering = 1; max_size = krb5_rc_io_size(context, &t->d); @@ -429,6 +438,8 @@ if (rc_store(context, id, rep) == CMP_MALLOC) { retval = KRB5_RC_MALLOC; goto io_fail; } + } else { + expired_entries++; } /* * free fields allocated by rc_io_fetch @@ -448,6 +459,9 @@ krb5_rc_free_entry(context, &rep); if (retval) krb5_rc_io_close(context, &t->d); + else if (expired_entries > EXCESSREPS) + retval = krb5_rc_dfl_expunge(context, id); + t->recovering = 0; return retval; #endif @@ -461,7 +475,7 @@ { int clientlen, serverlen, len; char *buf, *ptr; - unsigned long ret; + krb5_error_code ret; clientlen = strlen (rep->client) + 1; serverlen = strlen (rep->server) + 1; @@ -488,7 +502,7 @@ krb5_rcache id; krb5_donot_replay *rep; { - unsigned long ret; + krb5_error_code ret; struct dfl_data *t = (struct dfl_data *)id->data; switch(rc_store(context, id,rep)) { @@ -556,17 +570,20 @@ krb5_rcache tmp; krb5_deltat lifespan = t->lifespan; /* save original lifespan */ - name = t->name; - t->name = 0; /* Clear name so it isn't freed */ - (void) krb5_rc_dfl_close_no_free(context, id); - retval = krb5_rc_dfl_resolve(context, id, name); - free(name); - if (retval) - return retval; - retval = krb5_rc_dfl_recover(context, id); - if (retval) - return retval; - t = (struct dfl_data *)id->data; /* point to recovered cache */ + if (! t->recovering) { + name = t->name; + t->name = 0; /* Clear name so it isn't freed */ + (void) krb5_rc_dfl_close_no_free(context, id); + retval = krb5_rc_dfl_resolve(context, id, name); + free(name); + if (retval) + return retval; + retval = krb5_rc_dfl_recover(context, id); + if (retval) + return retval; + t = (struct dfl_data *)id->data; /* point to recovered cache */ + } + tmp = (krb5_rcache) malloc(sizeof(*tmp)); if (!tmp) return ENOMEM; >Audit-Trail: State-Changed-From-To: open-closed State-Changed-By: bjaspan State-Changed-When: Wed Nov 13 15:55:50 1996 State-Changed-Why: Duplicate of krb5-libs/132. I've forward the contents of this PR to that one. State-Changed-From-To: closed-open State-Changed-By: bjaspan State-Changed-When: Wed Nov 13 16:06:05 1996 State-Changed-Why: Re-opening until I figure out why I can't append this to krb5-libs/174. State-Changed-From-To: open-closed State-Changed-By: tytso State-Changed-When: Mon Nov 18 22:28:44 1996 State-Changed-Why: Fix applied >Unformatted: