[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