GPG Lockfile (concurrency) issue,
keyring lost: awarding 300$ for bugfix
Stefan Haller
Stefan.Haller at ascom.ch
Mon Aug 23 15:41:11 CEST 2004
Hallo Werner
Against what version of GnuPG am I intended to patch?
I tried to patch with
plain 1.2.5 ->fails partially,
1.2.5 with the initial patch -> complains that reversed or previously
applied patch was detected, after proceeding anyway -> fails partially,
1.2.5 with the initial and the previous patch (the unlink(NULL) attempt ->
about the same complain&failure as above
conflicts are in util/dotlock.c
Thanks
Stefan
Stefan Haller
Software Development
Transport Revenue
________________________________
Ascom Autelca Ltd.
Worbstrasse 201
CH-3073 Gümligen
Phone
Fax
+41 31 999 65 06
+41 31 999 65 82
stefan.haller at ascom.ch
www.ascom.com
Werner Koch <wk at gnupg.org>
23/08/04 14:33
To: Stefan Haller <Stefan.Haller at ascom.ch>
cc: gnupg-devel at gnupg.org
Subject: Re: GPG Lockfile (concurrency) issue, keyring lost: awarding 300$ for
bugfix
On Mon, 23 Aug 2004 13:28:41 +0200, Stefan Haller said:
> And sorry to bring bad news, it did not help. Unfortunately the combined
I did some more code staring and came up with this patch:
Werner
Index: util/dotlock.c
===================================================================
RCS file: /cvs/gnupg/gnupg/util/dotlock.c,v
retrieving revision 1.15.2.2
diff -u -r1.15.2.2 dotlock.c
--- util/dotlock.c 30 Jul 2003 16:04:46 -0000 1.15.2.2
+++ util/dotlock.c 23 Aug 2004 12:25:37 -0000
@@ -1,5 +1,5 @@
/* dotlock.c - dotfile locking
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software
Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation,
Inc.
*
* This file is part of GnuPG.
*
@@ -197,6 +197,45 @@
return h;
}
+
+void
+destroy_dotlock ( DOTLOCK h )
+{
+#if !defined (HAVE_DOSISH_SYSTEM)
+ if ( h )
+ {
+ DOTLOCK hprev, htmp;
+
+ /* First remove the handle from our global list of all locks. */
+ for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp,
htmp=htmp->next)
+ if (htmp == h)
+ {
+ if (hprev)
+ hprev->next = htmp->next;
+ else
+ all_lockfiles = htmp->next;
+ h->next = NULL;
+ break;
+ }
+
+ /* Second destroy the lock. */
+ if (!h->disable)
+ {
+ if (h->locked && h->lockname)
+ unlink (h->lockname);
+ if (h->tname)
+ unlink (h->tname);
+ m_free (h->tname);
+ m_free (h->lockname);
+ }
+ m_free(h);
+
+ }
+#endif
+}
+
+
+
static int
maybe_deadlock( DOTLOCK h )
{
@@ -317,9 +356,15 @@
#else
int pid;
- if( h->disable ) {
+ /* To avoid atexit race conditions we first check whether there
+ are any locks left. It might happen that another atexit
+ handler tries to release the lock while the atexit handler of
+ this module already ran and thus H is undefined. */
+ if(!all_lockfiles)
+ return 0;
+
+ if( h->disable )
return 0;
- }
if( !h->locked ) {
log_debug("oops, `%s' is not locked\n", h->lockname );
@@ -407,14 +452,7 @@
while( h ) {
h2 = h->next;
- if( !h->disable ) {
- if( h->locked )
- unlink( h->lockname );
- unlink(h->tname);
- m_free(h->tname);
- m_free(h->lockname);
- }
- m_free(h);
+ destroy_dotlock (h);
h = h2;
}
#endif
Index: util/dotlock.c
===================================================================
RCS file: /cvs/gnupg/gnupg/util/dotlock.c,v
retrieving revision 1.15.2.3
diff -u -r1.15.2.3 dotlock.c
--- util/dotlock.c 13 Aug 2004 17:00:02 -0000 1.15.2.3
+++ util/dotlock.c 23 Aug 2004 12:26:47 -0000
@@ -204,15 +204,32 @@
#if !defined (HAVE_DOSISH_SYSTEM)
if ( h )
{
+ DOTLOCK hprev, htmp;
+
+ /* First remove the handle from our global list of all locks. */
+ for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp,
htmp=htmp->next)
+ if (htmp == h)
+ {
+ if (hprev)
+ hprev->next = htmp->next;
+ else
+ all_lockfiles = htmp->next;
+ h->next = NULL;
+ break;
+ }
+
+ /* Second destroy the lock. */
if (!h->disable)
{
- if (h->locked)
+ if (h->locked && h->lockname)
unlink (h->lockname);
- unlink (h->tname);
+ if (h->tname)
+ unlink (h->tname);
m_free (h->tname);
m_free (h->lockname);
}
m_free(h);
+
}
#endif
}
@@ -339,9 +356,15 @@
#else
int pid;
- if( h->disable ) {
+ /* To avoid atexit race conditions we first check whether there
+ are any locks left. It might happen that another atexit
+ handler tries to release the lock while the atexit handler of
+ this module already ran and thus H is undefined. */
+ if(!all_lockfiles)
+ return 0;
+
+ if( h->disable )
return 0;
- }
if( !h->locked ) {
log_debug("oops, `%s' is not locked\n", h->lockname );
More information about the Gnupg-devel
mailing list