mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-12 22:11:29 +02:00
w32: Fix deadlock introduced by keybox_file_rename.
* g10/keyring.c (keyring_lock) [W32]: Flush the close cache before locking. * kbx/keybox-init.c (keybox_lock) [W32]: Close the file before locking. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
3b1248e007
commit
663c5d129a
@ -328,8 +328,20 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
|
|||||||
if (!keyring_is_writable(kr))
|
if (!keyring_is_writable(kr))
|
||||||
continue;
|
continue;
|
||||||
if (kr->is_locked)
|
if (kr->is_locked)
|
||||||
;
|
continue;
|
||||||
else if (dotlock_take (kr->lockhd, -1) ) {
|
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
/* Under Windows we need to CloseHandle the file before we
|
||||||
|
* try to lock it. This is because another process might
|
||||||
|
* have taken the lock and is using keybox_file_rename to
|
||||||
|
* rename the base file. How if our dotlock_take below is
|
||||||
|
* waiting for the lock but we have the base file still
|
||||||
|
* open, keybox_file_rename will never succeed as we are
|
||||||
|
* in a deadlock. */
|
||||||
|
iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0,
|
||||||
|
(char*)kr->fname);
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
if (dotlock_take (kr->lockhd, -1) ) {
|
||||||
log_info ("can't lock '%s'\n", kr->fname );
|
log_info ("can't lock '%s'\n", kr->fname );
|
||||||
rc = GPG_ERR_GENERAL;
|
rc = GPG_ERR_GENERAL;
|
||||||
}
|
}
|
||||||
@ -343,8 +355,9 @@ keyring_lock (KEYRING_HANDLE hd, int yes)
|
|||||||
if (!keyring_is_writable(kr))
|
if (!keyring_is_writable(kr))
|
||||||
continue;
|
continue;
|
||||||
if (!kr->is_locked)
|
if (!kr->is_locked)
|
||||||
;
|
continue;
|
||||||
else if (dotlock_release (kr->lockhd))
|
|
||||||
|
if (dotlock_release (kr->lockhd))
|
||||||
log_info ("can't unlock '%s'\n", kr->fname );
|
log_info ("can't unlock '%s'\n", kr->fname );
|
||||||
else
|
else
|
||||||
kr->is_locked = 0;
|
kr->is_locked = 0;
|
||||||
|
@ -286,27 +286,43 @@ keybox_lock (KEYBOX_HANDLE hd, int yes)
|
|||||||
|
|
||||||
if (yes) /* Take the lock. */
|
if (yes) /* Take the lock. */
|
||||||
{
|
{
|
||||||
if (kb->is_locked)
|
if (!kb->is_locked)
|
||||||
;
|
|
||||||
else if (dotlock_take (kb->lockhd, -1))
|
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
#ifdef HAVE_W32_SYSTEM
|
||||||
log_info ("can't lock '%s'\n", kb->fname );
|
/* Under Windows we need to close the file before we try
|
||||||
|
* to lock it. This is because another process might have
|
||||||
|
* taken the lock and is using keybox_file_rename to
|
||||||
|
* rename the base file. How if our dotlock_take below is
|
||||||
|
* waiting for the lock but we have the base file still
|
||||||
|
* open, keybox_file_rename will never succeed as we are
|
||||||
|
* in a deadlock. */
|
||||||
|
if (hd->fp)
|
||||||
|
{
|
||||||
|
fclose (hd->fp);
|
||||||
|
hd->fp = NULL;
|
||||||
|
}
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
if (dotlock_take (kb->lockhd, -1))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_info ("can't lock '%s'\n", kb->fname );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
kb->is_locked = 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
kb->is_locked = 1;
|
|
||||||
}
|
}
|
||||||
else /* Release the lock. */
|
else /* Release the lock. */
|
||||||
{
|
{
|
||||||
if (!kb->is_locked)
|
if (kb->is_locked)
|
||||||
;
|
|
||||||
else if (dotlock_release (kb->lockhd))
|
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
if (dotlock_release (kb->lockhd))
|
||||||
log_info ("can't unlock '%s'\n", kb->fname );
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_info ("can't unlock '%s'\n", kb->fname );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
kb->is_locked = 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
kb->is_locked = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user