summaryrefslogtreecommitdiffstats
path: root/g10/keydb.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2017-10-18 18:28:52 +0200
committerWerner Koch <wk@gnupg.org>2017-10-19 15:02:28 +0200
commit7c73db3d31c6457dfbdc82a8dc89951c023f0603 (patch)
treec9a14778d15e4cb06b617fe772f1225c12460183 /g10/keydb.c
parentgpg: Improve keydb handling in the main import function. (diff)
downloadgnupg2-7c73db3d31c6457dfbdc82a8dc89951c023f0603.tar.xz
gnupg2-7c73db3d31c6457dfbdc82a8dc89951c023f0603.zip
gpg: Keep a lock during the read-update/insert cycle in import.
* g10/keydb.c (keydb_handle): New field 'keep_lock'. (keydb_release): Clear that flag. (keydb_lock): New function. (unlock_all): Skip if KEEP_LOCK is set. * g10/getkey.c (get_keyblock_byfprint_fast): Call keep_lock if requested. -- That change is straightforward. It helps to avoid the race condition that another gpg process inserts a key while the first process is between the search and the insert. A similar change is due for gpgsm. Note that the key edit operations may still suffer from a race. GnuPG-bug-id: 3446
Diffstat (limited to 'g10/keydb.c')
-rw-r--r--g10/keydb.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/g10/keydb.c b/g10/keydb.c
index 0f28bc301..58a14a83d 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -96,6 +96,10 @@ struct keydb_handle
/ keybox_lock, as appropriate). */
int locked;
+ /* If this flag is set a lock will only be released by
+ * keydb_release. */
+ int keep_lock;
+
/* The index into ACTIVE of the resources in which the last search
result was found. Initially -1. */
int found;
@@ -964,6 +968,7 @@ keydb_release (KEYDB_HANDLE hd)
log_assert (active_handles > 0);
active_handles--;
+ hd->keep_lock = 0;
unlock_all (hd);
for (i=0; i < hd->used; i++)
{
@@ -985,6 +990,24 @@ keydb_release (KEYDB_HANDLE hd)
}
+/* Take a lock on the files immediately and not only during insert or
+ * update. This lock is released with keydb_release. */
+gpg_error_t
+keydb_lock (KEYDB_HANDLE hd)
+{
+ gpg_error_t err;
+
+ if (!hd)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ err = lock_all (hd);
+ if (!err)
+ hd->keep_lock = 1;
+
+ return err;
+}
+
+
/* Set a flag on the handle to suppress use of cached results. This
* is required for updating a keyring and for key listings. Fixme:
* Using a new parameter for keydb_new might be a better solution. */
@@ -1098,7 +1121,7 @@ unlock_all (KEYDB_HANDLE hd)
{
int i;
- if (!hd->locked)
+ if (!hd->locked || hd->keep_lock)
return;
for (i=hd->used-1; i >= 0; i--)