[git] GnuPG - branch, master, updated. gnupg-2.1.4-9-gfe5c6ed

by NIIBE Yutaka cvs at cvs.gnupg.org
Fri May 29 06:49:40 CEST 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  fe5c6edaed78839303d67e01e141cfc6b5de9aec (commit)
      from  6cb18a8f975b7ff7ca79c1fb0cddcd4b66be90fb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit fe5c6edaed78839303d67e01e141cfc6b5de9aec
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Thu May 28 17:08:37 2015 +0900

    g10: Fix a race condition initially creating trustdb.
    
    * g10/tdbio.c (take_write_lock, release_write_lock): New.
    (put_record_into_cache, tdbio_sync, tdbio_end_transaction): Use
    new lock functions.
    (tdbio_set_dbname): Fix the race.
    (open_db): Don't call dotlock_create.
    
    --
    
    GnuPG-bug-id: 1675

diff --git a/g10/tdbio.c b/g10/tdbio.c
index 98a7773..940165c 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -100,7 +100,33 @@ static int in_transaction;
 
 static void open_db(void);
 
+static int
+take_write_lock (void)
+{
+  if (!lockhandle)
+    lockhandle = dotlock_create (db_name, 0);
+  if (!lockhandle)
+    log_fatal ( _("can't create lock for '%s'\n"), db_name );
+
+  if (!is_locked)
+    {
+      if (dotlock_take (lockhandle, -1) )
+        log_fatal ( _("can't lock '%s'\n"), db_name );
+      else
+        is_locked = 1;
+      return 0;
+    }
+  else
+    return 1;
+}
 
+static void
+release_write_lock (void)
+{
+  if (!opt.lock_once)
+    if (!dotlock_release (lockhandle))
+      is_locked = 0;
+}
 

 /*************************************
  ************* record cache **********
@@ -256,12 +282,7 @@ put_record_into_cache( ulong recno, const char *data )
 	int n = dirty_count / 5; /* discard some dirty entries */
 	if( !n )
 	    n = 1;
-	if( !is_locked ) {
-	    if( dotlock_take( lockhandle, -1 ) )
-		log_fatal("can't acquire lock - giving up\n");
-	    else
-		is_locked = 1;
-	}
+        take_write_lock ();
 	for( unused = NULL, r = cache_list; r; r = r->next ) {
 	    if( r->flags.used && r->flags.dirty ) {
 		int rc = write_cache_item( r );
@@ -275,10 +296,7 @@ put_record_into_cache( ulong recno, const char *data )
 		    break;
 	    }
 	}
-	if( !opt.lock_once ) {
-	    if( !dotlock_release( lockhandle ) )
-		is_locked = 0;
-	}
+        release_write_lock ();
 	assert( unused );
 	r = unused;
 	r->flags.used = 1;
@@ -317,13 +335,9 @@ tdbio_sync()
     if( !cache_is_dirty )
 	return 0;
 
-    if( !is_locked ) {
-	if( dotlock_take( lockhandle, -1 ) )
-	    log_fatal("can't acquire lock - giving up\n");
-	else
-	    is_locked = 1;
-	did_lock = 1;
-    }
+    if (!take_write_lock ())
+        did_lock = 1;
+
     for( r = cache_list; r; r = r->next ) {
 	if( r->flags.used && r->flags.dirty ) {
 	    int rc = write_cache_item( r );
@@ -332,10 +346,8 @@ tdbio_sync()
 	}
     }
     cache_is_dirty = 0;
-    if( did_lock && !opt.lock_once ) {
-	if( !dotlock_release (lockhandle) )
-	    is_locked = 0;
-    }
+    if (did_lock)
+        release_write_lock ();
 
     return 0;
 }
@@ -372,20 +384,12 @@ tdbio_end_transaction()
 
     if( !in_transaction )
 	log_bug("tdbio: no active transaction\n");
-    if( !is_locked ) {
-	if( dotlock_take( lockhandle, -1 ) )
-	    log_fatal("can't acquire lock - giving up\n");
-	else
-	    is_locked = 1;
-    }
+    take_write_lock ();
     gnupg_block_all_signals();
     in_transaction = 0;
     rc = tdbio_sync();
     gnupg_unblock_all_signals();
-    if( !opt.lock_once ) {
-	if( !dotlock_release (lockhandle) )
-	    is_locked = 0;
-    }
+    release_write_lock ();
     return rc;
 }
 
@@ -483,6 +487,7 @@ int
 tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
 {
     char *fname;
+    struct stat statbuf;
     static int initialized = 0;
 
     if( !initialized ) {
@@ -504,6 +509,21 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
     else
       fname = xstrdup (new_dbname);
 
+    xfree (db_name);
+    db_name = fname;
+
+    /*
+     * Quick check for (likely) case where there is trustdb.gpg
+     * already.  This check is not required in theory, but it helps in
+     * practice, avoiding costly operations of preparing and taking
+     * the lock.
+     */
+    if (stat (fname, &statbuf) == 0 && statbuf.st_size > 0)
+      /* OK, we have the valid trustdb.gpg already.  */
+      return 0;
+
+    take_write_lock ();
+
     if( access( fname, R_OK ) ) {
 #ifdef HAVE_W32CE_SYSTEM
       /* We know how the cegcc implementation of access works ;-). */
@@ -512,11 +532,9 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
       else
         gpg_err_set_errno (EIO);
 #endif /*HAVE_W32CE_SYSTEM*/
-	if( errno != ENOENT ) {
-	    log_error( _("can't access '%s': %s\n"), fname, strerror(errno) );
-	    xfree(fname);
-	    return GPG_ERR_TRUSTDB;
-	}
+        if( errno != ENOENT )
+            log_fatal( _("can't access '%s': %s\n"), fname, strerror(errno) );
+
 	if (!create)
           *r_nofile = 1;
         else {
@@ -546,16 +564,6 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
 	    }
 	    *p = save_slash;
 
-	    xfree(db_name);
-	    db_name = fname;
-#ifdef __riscos__
-	    if( !lockhandle )
-              lockhandle = dotlock_create (db_name, 0);
-	    if( !lockhandle )
-		log_fatal( _("can't create lock for '%s'\n"), db_name );
-            if( dotlock_make (lockhandle, -1) )
-                log_fatal( _("can't lock '%s'\n"), db_name );
-#endif /* __riscos__ */
 	    oldmask=umask(077);
             if (is_secured_filename (fname)) {
                 fp = NULL;
@@ -573,13 +581,6 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
 		log_fatal (_("can't open '%s': %s\n"),
                            db_name, strerror (errno));
 
-#ifndef __riscos__
-	    if( !lockhandle )
-              lockhandle = dotlock_create (db_name, 0);
-	    if( !lockhandle )
-		log_fatal( _("can't create lock for '%s'\n"), db_name );
-#endif /* !__riscos__ */
-
             rc = create_version_record ();
 	    if( rc )
 		log_fatal( _("%s: failed to create version record: %s"),
@@ -590,12 +591,10 @@ tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
 
 	    if( !opt.quiet )
 		log_info(_("%s: trustdb created\n"), db_name);
-
-	    return 0;
 	}
     }
-    xfree(db_name);
-    db_name = fname;
+
+    release_write_lock ();
     return 0;
 }
 
@@ -615,14 +614,6 @@ open_db()
 
   assert( db_fd == -1 );
 
-  if (!lockhandle )
-    lockhandle = dotlock_create (db_name, 0);
-  if (!lockhandle )
-    log_fatal( _("can't create lock for '%s'\n"), db_name );
-#ifdef __riscos__
-  if (dotlock_take (lockhandle, -1) )
-    log_fatal( _("can't lock '%s'\n"), db_name );
-#endif /* __riscos__ */
 #ifdef HAVE_W32CE_SYSTEM
   {
     DWORD prevrc = 0;

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

Summary of changes:
 g10/tdbio.c | 121 ++++++++++++++++++++++++++++--------------------------------
 1 file changed, 56 insertions(+), 65 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list