[git] GnuPG - branch, STABLE-BRANCH-2-0, updated. gnupg-2.0.26-51-ga55c212

by Joshua Rogers cvs at cvs.gnupg.org
Thu Feb 12 18:48:15 CET 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, STABLE-BRANCH-2-0 has been updated
       via  a55c2125380aa2253ff13ea9b39e53d7b7df3db8 (commit)
       via  2b2adb85948ce2c7db727ebc0c99e8ad2c29bf5f (commit)
       via  f256bab03e2f191bc2e97fd2cc579d82c440b996 (commit)
      from  b2359db21c1eca7441c63b0791f8e3405b42ff83 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit a55c2125380aa2253ff13ea9b39e53d7b7df3db8
Author: Joshua Rogers <git at internot.info>
Date:   Fri Jan 30 11:42:52 2015 +0900

    kbx: Fix resource leak.
    
    * kbx/keybox-update.c (blob_filecopy): Fix resource leak.  On error
    return, 'fp' and 'newfp' was never closed.
    
    --
    
    Signed-off-by: Joshua Rogers <git at internot.info>
    
    [Log entry reformatted, and added more fixes - gniibe]
    
    (cherry picked from commit 7db6c82cec49b7c56c403a8ea98364086baf75f3)

diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c
index dfa7af3..410986c 100644
--- a/kbx/keybox-update.c
+++ b/kbx/keybox-update.c
@@ -237,11 +237,17 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
 
       rc = _keybox_write_header_blob (newfp);
       if (rc)
-        return rc;
+        {
+          fclose (newfp);
+          return rc;
+        }
 
       rc = _keybox_write_blob (blob, newfp);
       if (rc)
-        return rc;
+        {
+          fclose (newfp);
+          return rc;
+        }
 
       if ( fclose (newfp) )
         return gpg_error_from_syserror ();
@@ -264,7 +270,8 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
   rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
   if (rc)
     {
-      fclose(fp);
+      fclose (fp);
+      fclose (newfp);
       goto leave;
     }
   
@@ -277,12 +284,16 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
           if (fwrite (buffer, nread, 1, newfp) != 1)
             {
               rc = gpg_error_from_syserror ();
+              fclose (fp);
+              fclose (newfp);
               goto leave;
             }
         }
       if (ferror (fp))
         {
           rc = gpg_error_from_syserror ();
+          fclose (fp);
+          fclose (newfp);
           goto leave;
         }
     }
@@ -306,19 +317,27 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
           if (fwrite (buffer, nread, 1, newfp) != 1)
             {
               rc = gpg_error_from_syserror ();
+              fclose (fp);
+              fclose (newfp);
               goto leave;
             }
         }
       if (ferror (fp))
         {
           rc = gpg_error_from_syserror ();
+          fclose (fp);
+          fclose (newfp);
           goto leave;
         }
       
       /* Skip this blob. */
       rc = _keybox_read_blob (NULL, fp);
       if (rc)
-        return rc;
+        {
+          fclose (fp);
+          fclose (newfp);
+          return rc;
+        }
     }
   
   /* Do an insert or update. */
@@ -326,7 +345,11 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
     { 
       rc = _keybox_write_blob (blob, newfp);
       if (rc)
+        {
+          fclose (fp);
+          fclose (newfp);
           return rc;
+        }
     }
   
   /* Copy the rest of the packet for an delete or update. */
@@ -337,12 +360,16 @@ blob_filecopy (int mode, const char *fname, KEYBOXBLOB blob,
           if (fwrite (buffer, nread, 1, newfp) != 1)
             {
               rc = gpg_error_from_syserror ();
+              fclose (fp);
+              fclose (newfp);
               goto leave;
             }
         }
       if (ferror (fp))
         {
           rc = gpg_error_from_syserror ();
+          fclose (fp);
+          fclose (newfp);
           goto leave;
         }
     }
@@ -614,7 +641,7 @@ keybox_compress (KEYBOX_HANDLE hd)
   rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
   if (rc)
     {
-      fclose(fp);
+      fclose (fp);
       return rc;;
     }
 

commit 2b2adb85948ce2c7db727ebc0c99e8ad2c29bf5f
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 12 18:45:08 2015 +0100

    gpg: Limit the size of key packets to a sensible value.
    
    * g10/parse-packet.c (MAX_KEY_PACKET_LENGTH): New.
    (MAX_UID_PACKET_LENGTH): New.
    (MAX_COMMENT_PACKET_LENGTH): New.
    (MAX_ATTR_PACKET_LENGTH): New.
    (parse_key): Limit the size of a key packet to 256k.
    (parse_user_id): Use macro for the packet size limit.
    (parse_attribute): Ditto.
    (parse_comment): Ditto.
    --
    
    Without that it is possible to force gpg to allocate large amounts of
    memory by using a bad encoded MPI.  This would be an too easy DoS.
    Another way to mitigate would be to change the MPI read function to
    allocate memory dynamically while reading the MPI.  However, that
    complicates and possibly slows down the code.  A too large key packet
    is in any case a sign for broken data and thus gpg should not use it.
    
    Reported-by: Hanno Böck
    GnuPG-bug-id: 1823
    Signed-off-by: Werner Koch <wk at gnupg.org>
    
    (back ported from commit 382ba4b137b42d5f25a7e256bb7c053ee5ac7b64)

diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 1048402..c374477 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -35,6 +35,14 @@
 #include "main.h"
 #include "i18n.h"
 
+
+/* Maximum length of packets to avoid excessive memory allocation.  */
+#define MAX_KEY_PACKET_LENGTH     (256 * 1024)
+#define MAX_UID_PACKET_LENGTH     (  2 * 1024)
+#define MAX_COMMENT_PACKET_LENGTH ( 64 * 1024)
+#define MAX_ATTR_PACKET_LENGTH    ( 16 * 1024*1024)
+
+
 static int mpi_print_mode;
 static int list_mode;
 static FILE *listfp;
@@ -1741,6 +1749,13 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
         rc = gpg_error (GPG_ERR_INV_PACKET);
 	goto leave;
     }
+    else if (pktlen > MAX_KEY_PACKET_LENGTH) {
+        log_error ("packet(%d) too large\n", pkttype);
+        if (list_mode)
+            fputs (":key packet: [too large]\n", listfp);
+        rc = gpg_error (GPG_ERR_INV_PACKET);
+        goto leave;
+    }
 
     timestamp = read_32(inp); pktlen -= 4;
     if( is_v4 ) {
@@ -2158,7 +2173,7 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
        allocatable, and a very large pktlen could actually cause our
        allocation to wrap around in xmalloc to a small number. */
 
-    if (pktlen > 2048)
+    if (pktlen > MAX_UID_PACKET_LENGTH)
       {
 	log_error ("packet(%d) too large\n", pkttype);
 	iobuf_skip_rest(inp, pktlen, 0);
@@ -2232,7 +2247,7 @@ parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
     /* We better cap the size of an attribute packet to make DoS not
        too easy.  16MB should be more then enough for one attribute
        packet (ie. a photo).  */
-    if (pktlen > 16*1024*1024) {
+    if (pktlen > MAX_ATTR_PACKET_LENGTH) {
         log_error ("packet(%d) too large\n", pkttype);
         if (list_mode)
           fprintf (listfp, ":attribute packet: [too large]\n");
@@ -2274,7 +2289,7 @@ parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
        overflow in the malloc below.  Comment packets are actually not
        anymore define my OpenPGP and we even stopped to use our
        private comment packet. */
-    if (pktlen>65536)
+    if (pktlen > MAX_COMMENT_PACKET_LENGTH)
       {
 	log_error ("packet(%d) too large\n", pkttype);
 	iobuf_skip_rest (inp, pktlen, 0);

commit f256bab03e2f191bc2e97fd2cc579d82c440b996
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Feb 12 18:26:58 2015 +0100

    Avoid double-close in unusual dotlock situations.
    
    * jnlib/dotlock.c (create_dotlock): Avoid double close due to EINTR.
    --
    
    close(2) says:
    
      close() should not be retried after an EINTR since this may cause a
      reused descriptor from another thread to be closed.
    
    (backported from commit 628b111fa679612e23c0d46505b1ecbbf091897d)
    
    Debian-Bug-Id: 773423
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c
index 260c086..2578658 100644
--- a/jnlib/dotlock.c
+++ b/jnlib/dotlock.c
@@ -1,5 +1,5 @@
 /* dotlock.c - dotfile locking
- * Copyright (C) 1998, 2000, 2001, 2003, 2004, 
+ * Copyright (C) 1998, 2000, 2001, 2003, 2004,
  *               2005, 2006, 2008 Free Software Foundation, Inc.
  *
  * This file is part of JNLIB.
@@ -58,7 +58,7 @@
 
 
 /* The object describing a lock.  */
-struct dotlock_handle 
+struct dotlock_handle
 {
   struct dotlock_handle *next;
   char *lockname;      /* Name of the actual lockfile.          */
@@ -109,7 +109,7 @@ disable_dotlock(void)
    Calling this function with NULL does only install the atexit
    handler and may thus be used to assure that the cleanup is called
    after all other atexit handlers.
-  
+
    This function creates a lock file in the same directory as
    FILE_TO_LOCK using that name and a suffix of ".lock".  Note that on
    POSIX systems a temporary file ".#lk.<hostname>.pid[.threadid] is
@@ -171,7 +171,7 @@ create_dotlock (const char *file_to_lock)
     nodename = "unknown";
   else
     nodename = utsbuf.nodename;
-  
+
 #ifdef __riscos__
   {
     char *iter = (char *) nodename;
@@ -220,15 +220,15 @@ create_dotlock (const char *file_to_lock)
             "%s/%d", nodename, (int)getpid () );
 #endif /* __riscos__ */
 
-  do 
+  do
     {
       errno = 0;
       fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
                  S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
-    } 
+    }
   while (fd == -1 && errno == EINTR);
 
-  if ( fd == -1 ) 
+  if ( fd == -1 )
     {
       all_lockfiles = h->next;
       log_error (_("failed to create temporary file `%s': %s\n"),
@@ -244,7 +244,12 @@ create_dotlock (const char *file_to_lock)
   if ( write (fd, "\n", 1 ) != 1 )
     goto write_failed;
   if ( close (fd) )
-    goto write_failed;
+    {
+      if ( errno == EINTR )
+        fd = -1;
+      goto write_failed;
+    }
+  fd = -1;
 
 # ifdef _REENTRANT
   /* release mutex */
@@ -267,7 +272,8 @@ create_dotlock (const char *file_to_lock)
   /* fixme: release mutex */
 # endif
   log_error ( _("error writing to `%s': %s\n"), h->tname, strerror(errno) );
-  close (fd);
+  if (fd != -1)
+    close (fd);
   unlink (h->tname);
   jnlib_free (h->tname);
   jnlib_free (h);
@@ -300,7 +306,7 @@ create_dotlock (const char *file_to_lock)
      reasons why a lock file can't be created and thus the process
      would not stop as expected but spin til until Windows crashes.
      Our solution is to keep the lock file open; that does not
-     harm. */ 
+     harm. */
   h->lockhd = CreateFile (h->lockname,
                           GENERIC_READ|GENERIC_WRITE,
                           FILE_SHARE_READ|FILE_SHARE_WRITE,
@@ -339,7 +345,7 @@ destroy_dotlock ( DOTLOCK h )
         h->next = NULL;
         break;
       }
-  
+
   /* Then destroy the lock. */
   if (!h->disable)
     {
@@ -395,7 +401,7 @@ make_dotlock ( DOTLOCK h, long timeout )
   if ( h->disable )
     return 0; /* Locks are completely disabled.  Return success. */
 
-  if ( h->locked ) 
+  if ( h->locked )
     {
 #ifndef __riscos__
       log_debug ("Oops, `%s' is already locked\n", h->lockname);
@@ -419,19 +425,19 @@ make_dotlock ( DOTLOCK h, long timeout )
           return -1;
 	}
 # else /* __riscos__ */
-      if ( !renamefile(h->tname, h->lockname) ) 
+      if ( !renamefile(h->tname, h->lockname) )
         {
           h->locked = 1;
           return 0; /* okay */
         }
-      if ( errno != EEXIST ) 
+      if ( errno != EEXIST )
         {
           log_error( "lock not made: rename() failed: %s\n", strerror(errno) );
           return -1;
         }
 # endif /* __riscos__ */
 
-      if ( (pid = read_lockfile (h, &same_node)) == -1 ) 
+      if ( (pid = read_lockfile (h, &same_node)) == -1 )
         {
           if ( errno != ENOENT )
             {
@@ -461,11 +467,11 @@ make_dotlock ( DOTLOCK h, long timeout )
 # endif /* __riscos__ */
 	}
 
-      if ( timeout == -1 ) 
+      if ( timeout == -1 )
         {
           /* Wait until lock has been released. */
           struct timeval tv;
-          
+
           log_info (_("waiting for lock (held by %d%s) %s...\n"),
                     pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
 
@@ -495,7 +501,7 @@ make_dotlock ( DOTLOCK h, long timeout )
           return -1;
         }
 
-      if ( timeout == -1 ) 
+      if ( timeout == -1 )
         {
           /* Wait until lock has been released. */
           log_info (_("waiting for lock %s...\n"), h->lockname);
@@ -545,7 +551,7 @@ release_dotlock( DOTLOCK h )
 #else
 
   pid = read_lockfile (h, &same_node);
-  if ( pid == -1 ) 
+  if ( pid == -1 )
     {
       log_error( "release_dotlock: lockfile error\n");
       return -1;
@@ -566,7 +572,7 @@ release_dotlock( DOTLOCK h )
   /* Fixme: As an extra check we could check whether the link count is
      now really at 1. */
 #else /* __riscos__ */
-  if ( renamefile (h->lockname, h->tname) ) 
+  if ( renamefile (h->lockname, h->tname) )
     {
       log_error ("release_dotlock: error renaming lockfile `%s' to `%s'\n",
                  h->lockname, h->tname);
@@ -594,7 +600,7 @@ read_lockfile (DOTLOCK h, int *same_node )
   char *buffer, *p;
   size_t expected_len;
   int res, nread;
-  
+
   *same_node = 0;
   expected_len = 10 + 1 + h->nodename_len + 1;
   if ( expected_len >= sizeof buffer_space)
@@ -627,7 +633,7 @@ read_lockfile (DOTLOCK h, int *same_node )
       if (res < 0)
         {
           log_info ("error reading lockfile `%s'", h->lockname );
-          close (fd); 
+          close (fd);
           if (buffer != buffer_space)
             jnlib_free (buffer);
           errno = 0; /* Do not return an inappropriate ERRNO. */
@@ -651,7 +657,7 @@ read_lockfile (DOTLOCK h, int *same_node )
   if (buffer[10] != '\n'
       || (buffer[10] = 0, pid = atoi (buffer)) == -1
 #ifndef __riscos__
-      || !pid 
+      || !pid
 #else /* __riscos__ */
       || (!pid && riscos_getpid())
 #endif /* __riscos__ */
@@ -665,7 +671,7 @@ read_lockfile (DOTLOCK h, int *same_node )
     }
 
   if (nread == expected_len
-      && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len) 
+      && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
       && buffer[11+h->nodename_len] == '\n')
     *same_node = 1;
 
@@ -683,10 +689,10 @@ void
 dotlock_remove_lockfiles()
 {
   DOTLOCK h, h2;
-  
+
   h = all_lockfiles;
   all_lockfiles = NULL;
-    
+
   while ( h )
     {
       h2 = h->next;

-----------------------------------------------------------------------

Summary of changes:
 g10/parse-packet.c  | 21 ++++++++++++++++---
 jnlib/dotlock.c     | 58 +++++++++++++++++++++++++++++------------------------
 kbx/keybox-update.c | 37 +++++++++++++++++++++++++++++-----
 3 files changed, 82 insertions(+), 34 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list