1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-31 22:18:03 +02:00

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) {} void dotlock_disable(void) {}
dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags) dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags)
{ return NULL; } { 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_take (dotlock_t h, long timeout) { return 0;}
int dotlock_release (dotlock_t h) {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) if (lockhd)
{ {
dotlock_release (lockhd); dotlock_release (lockhd);
dotlock_destroy (lockhd); dotlock_destroy (lockhd, 1);
} }
return rc; return rc;
} }

View File

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

View File

@ -101,10 +101,11 @@ void dotlock_disable (void);
dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags); dotlock_t dotlock_create (const char *file_to_lock, unsigned int flags);
void dotlock_set_fd (dotlock_t h, int fd); void dotlock_set_fd (dotlock_t h, int fd);
int dotlock_get_fd (dotlock_t h); 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_take (dotlock_t h, long timeout);
int dotlock_release (dotlock_t h); 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 #ifdef __cplusplus
} }

View File

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