[git] GnuPG - branch, STABLE-BRANCH-1-4, updated. gnupg-1.4.19-3-g506eb6f

by Werner Koch cvs at cvs.gnupg.org
Sun Apr 5 19:44:45 CEST 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-1-4 has been updated
       via  506eb6fec67f170827777f2f44ced6f50745a0ad (commit)
      from  f34d88364a984947bcd7c344f9532f683b856353 (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 506eb6fec67f170827777f2f44ced6f50745a0ad
Author: Werner Koch <wk at gnupg.org>
Date:   Sun Apr 5 19:42:59 2015 +0200

    gpg: Fix DoS while parsing mangled secret key packets.
    
    * g10/parse-packet.c (parse_key): Check PKTLEN before calling mpi_read
    et al.
    --
    
    Due to the missing length checks PKTLEN may turn negative.  Because
    PKTLEN is an unsigned int the malloc in read_rest would try to malloc
    a too large number and terminate the process with "error reading rest
    of packet: Cannot allocate memory".
    
    Reported-by: Hanno Böck.
    Signed-off-by: Werner Koch <wk at gnupg.org>
    (backported from 2.0 commit 0aac920f23fd07e152fdb7385299c92bb9a4ade3)

diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 862ec6e..8d4450c 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -1747,6 +1747,12 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
 	byte temp[16];
         size_t snlen = 0;
 
+        if (pktlen < 1)
+          {
+            rc = G10ERR_INVALID_PACKET;
+            goto leave;
+          }
+
 	if( !npkey ) {
 	    sk->skey[0] = mpi_set_opaque( NULL,
 					  read_rest(inp, pktlen, 0), pktlen );
@@ -1755,7 +1761,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
 	}
 
 	for(i=0; i < npkey; i++ ) {
-	    n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
+	    n = pktlen;
+            sk->skey[i] = mpi_read(inp, &n, 0 );
+            pktlen -=n;
 	    if( list_mode ) {
 		fprintf (listfp,   "\tskey[%d]: ", i);
 		mpi_print(listfp, sk->skey[i], mpi_print_mode  );
@@ -1769,7 +1777,8 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
         if (list_mode && npkey)
             keyid_from_sk (sk, keyid);
 
-	sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
+	sk->protect.algo = iobuf_get_noeof(inp);
+        pktlen--;
         sk->protect.sha1chk = 0;
 	if( sk->protect.algo ) {
 	    sk->is_protected = 1;
@@ -1780,12 +1789,15 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
 		    goto leave;
 		}
                 sk->protect.sha1chk = (sk->protect.algo == 254);
-		sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
+		sk->protect.algo = iobuf_get_noeof(inp);
+                pktlen--;
 		/* Note that a sk->protect.algo > 110 is illegal, but
 		   I'm not erroring on it here as otherwise there
 		   would be no way to delete such a key. */
-		sk->protect.s2k.mode  = iobuf_get_noeof(inp); pktlen--;
-		sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
+		sk->protect.s2k.mode  = iobuf_get_noeof(inp);
+                pktlen--;
+		sk->protect.s2k.hash_algo = iobuf_get_noeof(inp);
+                pktlen--;
 		/* check for the special GNU extension */
 		if( is_v4 && sk->protect.s2k.mode == 101 ) {
 		    for(i=0; i < 4 && pktlen; i++, pktlen-- )
@@ -1940,6 +1952,11 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
 	    /* ugly; the length is encrypted too, so we read all
 	     * stuff up to the end of the packet into the first
 	     * skey element */
+	    if (pktlen < 2) /* At least two bytes for the length.  */
+	      {
+                rc = G10ERR_INVALID_PACKET;
+                goto leave;
+	      }
 	    sk->skey[npkey] = mpi_set_opaque(NULL,
 					     read_rest(inp, pktlen, 0),pktlen);
 	    pktlen = 0;
@@ -1955,6 +1972,11 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
                         fprintf (listfp,   "\tskey[%d]: [encrypted]\n", i);
                 }
                 else {
+                    if (pktlen < 2) /* At least two bytes for the length.  */
+                      {
+                        rc = G10ERR_INVALID_PACKET;
+                        goto leave;
+	              }
                     n = pktlen;
                     sk->skey[i] = mpi_read(inp, &n, 0 );
                     pktlen -=n;
@@ -1971,7 +1993,13 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
             if (rc)
                 goto leave;
 
-	    sk->csum = read_16(inp); pktlen -= 2;
+            if (pktlen < 2)
+              {
+                rc = G10ERR_INVALID_PACKET;
+                goto leave;
+              }
+	    sk->csum = read_16(inp);
+            pktlen -= 2;
 	    if( list_mode ) {
 		fprintf (listfp, "\tchecksum: %04hx\n", sk->csum);
 	    }
@@ -1980,6 +2008,12 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
     else {
 	PKT_public_key *pk = pkt->pkt.public_key;
 
+        if (pktlen < 1)
+          {
+            rc = G10ERR_INVALID_PACKET;
+            goto leave;
+          }
+
 	if( !npkey ) {
 	    pk->pkey[0] = mpi_set_opaque( NULL,
 					  read_rest(inp, pktlen, 0), pktlen );
@@ -1988,7 +2022,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
 	}
 
 	for(i=0; i < npkey; i++ ) {
-	    n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
+	    n = pktlen;
+            pk->pkey[i] = mpi_read(inp, &n, 0 );
+            pktlen -=n;
 	    if( list_mode ) {
 		fprintf (listfp,   "\tpkey[%d]: ", i);
 		mpi_print(listfp, pk->pkey[i], mpi_print_mode  );

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

Summary of changes:
 g10/parse-packet.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 7 deletions(-)


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




More information about the Gnupg-commits mailing list