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