mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-08 12:44:23 +01:00
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
This commit is contained in:
parent
3bb06531d3
commit
645f30ad31
15
g10/getkey.c
15
g10/getkey.c
@ -1877,14 +1877,25 @@ get_keyblock_byfprint_fast (kbnode_t *r_keyblock, KEYDB_HANDLE *r_hd,
|
|||||||
hd = keydb_new ();
|
hd = keydb_new ();
|
||||||
if (!hd)
|
if (!hd)
|
||||||
return gpg_error_from_syserror ();
|
return gpg_error_from_syserror ();
|
||||||
if (r_hd)
|
|
||||||
*r_hd = hd;
|
|
||||||
|
|
||||||
if (lock)
|
if (lock)
|
||||||
{
|
{
|
||||||
|
err = keydb_lock (hd);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
/* If locking did not work, we better don't return a handle
|
||||||
|
* at all - there was a reason that locking has been
|
||||||
|
* requested. */
|
||||||
|
keydb_release (hd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
keydb_disable_caching (hd);
|
keydb_disable_caching (hd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fo all other errors we return the handle. */
|
||||||
|
if (r_hd)
|
||||||
|
*r_hd = hd;
|
||||||
|
|
||||||
err = keydb_search_fpr (hd, fprbuf);
|
err = keydb_search_fpr (hd, fprbuf);
|
||||||
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||||
{
|
{
|
||||||
|
25
g10/keydb.c
25
g10/keydb.c
@ -96,6 +96,10 @@ struct keydb_handle
|
|||||||
/ keybox_lock, as appropriate). */
|
/ keybox_lock, as appropriate). */
|
||||||
int locked;
|
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
|
/* The index into ACTIVE of the resources in which the last search
|
||||||
result was found. Initially -1. */
|
result was found. Initially -1. */
|
||||||
int found;
|
int found;
|
||||||
@ -964,6 +968,7 @@ keydb_release (KEYDB_HANDLE hd)
|
|||||||
log_assert (active_handles > 0);
|
log_assert (active_handles > 0);
|
||||||
active_handles--;
|
active_handles--;
|
||||||
|
|
||||||
|
hd->keep_lock = 0;
|
||||||
unlock_all (hd);
|
unlock_all (hd);
|
||||||
for (i=0; i < hd->used; i++)
|
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
|
/* Set a flag on the handle to suppress use of cached results. This
|
||||||
* is required for updating a keyring and for key listings. Fixme:
|
* is required for updating a keyring and for key listings. Fixme:
|
||||||
* Using a new parameter for keydb_new might be a better solution. */
|
* Using a new parameter for keydb_new might be a better solution. */
|
||||||
@ -1098,7 +1121,7 @@ unlock_all (KEYDB_HANDLE hd)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!hd->locked)
|
if (!hd->locked || hd->keep_lock)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i=hd->used-1; i >= 0; i--)
|
for (i=hd->used-1; i >= 0; i--)
|
||||||
|
@ -154,6 +154,10 @@ KEYDB_HANDLE keydb_new (void);
|
|||||||
/* Free all resources owned by the database handle. */
|
/* Free all resources owned by the database handle. */
|
||||||
void keydb_release (KEYDB_HANDLE hd);
|
void 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);
|
||||||
|
|
||||||
/* Set a flag on the handle to suppress use of cached results. This
|
/* Set a flag on the handle to suppress use of cached results. This
|
||||||
is required for updating a keyring and for key listings. Fixme:
|
is required for updating a keyring and for key listings. Fixme:
|
||||||
Using a new parameter for keydb_new might be a better solution. */
|
Using a new parameter for keydb_new might be a better solution. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user