gpg: signal handling fix

* include/dotlock.h (dotlock_remove_lockfiles_reclaim): New.
  (dotlock_destroy, dotlock_remove_lockfiles): Add a flag to reclaim
  memory or not.
* util/dotlock.c (dotlock_create): Use
  dotlock_remove_lockfiles_reclaim for atexit.
  (dotlock_destroy_unix, dotlock_destroy)
  (dotlock_remove_lockfiles): Add a reclaim flag.
  (dotlock_remove_lockfiles_reclaim): New.
* g10/signal.c (got_fatal_signal): Disable flag of reclaim memory to
  avoid non-async-face call.
* g10/keydb.c (maybe_create_keyring): Follow the API change.
* g10/gpgv.c: Follow the API change.

--

signal handler got_fatal_signal should not call non-async-signal-safe
functions.  When malloc is interrupted by a signal, it screws up.

This issue is reported:
https://bugs.g10code.com/gnupg/issue1515
http://bugs.debian.org/399904
This commit is contained in:
NIIBE Yutaka 2013-07-12 17:26:55 +09:00
parent 6f0ec6ab48
commit 212a325d42
5 changed files with 32 additions and 17 deletions

View File

@ -434,7 +434,7 @@ void rl_free_line_state (void) {}
void dotlock_disable(void) {}
dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags)
{ return NULL; }
void dotlock_destroy (dotlock_t h) {}
void dotlock_destroy (dotlock_t h, int reclaim) {}
int dotlock_take (dotlock_t h, long timeout) { return 0;}
int dotlock_release (dotlock_t h) {return 0;}
void dotlock_remove_lockfiles (void) {}
void dotlock_remove_lockfiles (void, int reclaim) {}

View File

@ -181,7 +181,7 @@ maybe_create_keyring (char *filename, int force)
if (lockhd)
{
dotlock_release (lockhd);
dotlock_destroy (lockhd);
dotlock_destroy (lockhd, 1);
}
return rc;
}

View File

@ -122,7 +122,7 @@ got_fatal_signal( int sig )
/* Reset action to default action and raise signal again. */
init_one_signal (sig, SIG_DFL, 0);
dotlock_remove_lockfiles ();
dotlock_remove_lockfiles (0);
#ifdef __riscos__
riscos_close_fds ();
#endif /* __riscos__ */

View File

@ -101,10 +101,11 @@ void dotlock_disable (void);
dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags);
void dotlock_set_fd (dotlock_t h, int fd);
int dotlock_get_fd (dotlock_t h);
void dotlock_destroy (dotlock_t h);
void dotlock_destroy (dotlock_t h, int reclaim);
int dotlock_take (dotlock_t h, long timeout);
int dotlock_release (dotlock_t h);
void dotlock_remove_lockfiles (void);
void dotlock_remove_lockfiles (int reclaim);
void dotlock_remove_lockfiles_reclaim (void);
#ifdef __cplusplus
}

View File

@ -128,7 +128,7 @@
unlinked using the atexit handler. If you don't need the lock file
anymore, you may also explicitly remove it with a call to:
dotlock_destroy (h);
dotlock_destroy (h, 1);
To actually lock the file, you use:
@ -823,7 +823,7 @@ dotlock_create (const char *file_to_lock, unsigned int flags)
if ( !initialized )
{
atexit (dotlock_remove_lockfiles);
atexit (dotlock_remove_lockfiles_reclaim);
initialized = 1;
}
@ -881,13 +881,14 @@ dotlock_get_fd (dotlock_t h)
#ifdef HAVE_POSIX_SYSTEM
/* Unix specific code of destroy_dotlock. */
static void
dotlock_destroy_unix (dotlock_t h)
dotlock_destroy_unix (dotlock_t h, int reclaim)
{
if (h->locked && h->lockname)
unlink (h->lockname);
if (h->tname && !h->use_o_excl)
unlink (h->tname);
jnlib_free (h->tname);
if (reclaim)
jnlib_free (h->tname);
}
#endif /*HAVE_POSIX_SYSTEM*/
@ -911,7 +912,7 @@ dotlock_destroy_w32 (dotlock_t h)
/* Destroy the locck handle H and release the lock. */
void
dotlock_destroy (dotlock_t h)
dotlock_destroy (dotlock_t h, int reclaim)
{
dotlock_t hprev, htmp;
@ -938,11 +939,13 @@ dotlock_destroy (dotlock_t h)
#ifdef HAVE_DOSISH_SYSTEM
dotlock_destroy_w32 (h);
#else /* !HAVE_DOSISH_SYSTEM */
dotlock_destroy_unix (h);
dotlock_destroy_unix (h, reclaim);
#endif /* HAVE_DOSISH_SYSTEM */
jnlib_free (h->lockname);
if (reclaim)
jnlib_free (h->lockname);
}
jnlib_free(h);
if (reclaim)
jnlib_free (h);
}
@ -1284,9 +1287,14 @@ dotlock_release (dotlock_t h)
/* Remove all lockfiles. This is called by the atexit handler
installed by this module but may also be called by other
termination handlers. */
termination handlers.
When RECLAIM == 0, it doesn't reclaim memory allocated.
This is useful calling by signal handlers.
*/
void
dotlock_remove_lockfiles (void)
dotlock_remove_lockfiles (int reclaim)
{
dotlock_t h, h2;
@ -1301,7 +1309,13 @@ dotlock_remove_lockfiles (void)
while ( h )
{
h2 = h->next;
dotlock_destroy (h);
dotlock_destroy (h, reclaim);
h = h2;
}
}
void
dotlock_remove_lockfiles_reclaim (void)
{
dotlock_remove_lockfiles (1);
}