gpg: signal handling fix
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 12 Jul 2013 08:26:55 +0000 (17:26 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 12 Jul 2013 08:26:55 +0000 (17:26 +0900)
* 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

g10/gpgv.c
g10/keydb.c
g10/signal.c
include/dotlock.h
util/dotlock.c

index 9ee8032..2d51829 100644 (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) {}
index d6d83e2..8be1945 100644 (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;
 }
index 086bf51..44b863d 100644 (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__ */
index 920a81a..0453792 100644 (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
 }
index c5f3a78..27c2bb2 100644 (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:
 
-     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)
 \f
 /* 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);
+}