ports/opt (2.2): [notify] gnupg: http://lists.gnupg.org/pipermail/gnupg-announce/2006q4/000246.html

crux at crux.nu crux at crux.nu
Thu Dec 7 18:44:27 UTC 2006


commit 1705d71ca4cbcacf271d6c727e75586bab78e517
Author: Simon Gloßner <viper at hometux.de>
Date:   Thu Dec 7 19:44:21 2006 +0100

    [notify] gnupg: http://lists.gnupg.org/pipermail/gnupg-announce/2006q4/000246.html

diff --git a/gnupg/.md5sum b/gnupg/.md5sum
index d7bf840..d1dd5ad 100644
--- a/gnupg/.md5sum
+++ b/gnupg/.md5sum
@@ -1 +1,2 @@
+9e62d88ab621b465f0496f5fea9f38a7  filter-context-20-small.diff
 eb24e258db73f4cb53a3ce18375efa21  gnupg-2.0.1.tar.bz2
diff --git a/gnupg/Pkgfile b/gnupg/Pkgfile
index 864fbba..b2a5b2a 100644
--- a/gnupg/Pkgfile
+++ b/gnupg/Pkgfile
@@ -6,12 +6,18 @@
 
 name=gnupg
 version=2.0.1
-release=2
-source=(ftp://ftp.gnupg.org/gcrypt/$name/$name-$version.tar.bz2)
+release=3
+source=(ftp://ftp.gnupg.org/gcrypt/$name/$name-$version.tar.bz2 \
+	filter-context-20-small.diff)
 
 build () {
     cd $name-$version
 
+    ( 
+	cd g10
+	patch -p0 < $SRC/filter-context-20-small.diff 
+    )
+
     ./configure \
 	--prefix=/usr \
 	--libexecdir=/usr/lib \
diff --git a/gnupg/filter-context-20-small.diff b/gnupg/filter-context-20-small.diff
new file mode 100644
index 0000000..c7a7f5c
--- /dev/null
+++ b/gnupg/filter-context-20-small.diff
@@ -0,0 +1,260 @@
+This is a patch against GnuPG 2.0.1. Change the directory to g10/ and
+apply this patch.
+
+2006-12-02  Werner Koch  <wk at g10code.com>
+
+	* encr-data.c: Allocate DFX context on the heap and not on the
+	stack.  Changes at several places.  Fixes CVE-2006-6235.
+	
+
+Index: encr-data.c
+===================================================================
+--- encr-data.c	(revision 4352)
++++ encr-data.c	(working copy)
+@@ -39,16 +39,37 @@
+ static int decode_filter ( void *opaque, int control, IOBUF a,
+ 					byte *buf, size_t *ret_len);
+ 
+-typedef struct 
++typedef struct decode_filter_context_s
+ {
+   gcry_cipher_hd_t cipher_hd;
+   gcry_md_hd_t mdc_hash;
+   char defer[22];
+   int  defer_filled;
+   int  eof_seen;
+-} decode_filter_ctx_t;
++  int  refcount;
++} *decode_filter_ctx_t;
+ 
+ 
++/* Helper to release the decode context.  */
++static void
++release_dfx_context (decode_filter_ctx_t dfx)
++{
++  if (!dfx)
++    return;
++
++  assert (dfx->refcount);
++  if ( !--dfx->refcount )
++    {
++      gcry_cipher_close (dfx->cipher_hd);
++      dfx->cipher_hd = NULL;
++      gcry_md_close (dfx->mdc_hash);
++      dfx->mdc_hash = NULL;
++      xfree (dfx);
++    }
++}
++
++
++
+ /****************
+  * Decrypt the data, specified by ED with the key DEK.
+  */
+@@ -62,7 +83,11 @@
+   unsigned blocksize;
+   unsigned nprefix;
+   
+-  memset( &dfx, 0, sizeof dfx );
++  dfx = xtrycalloc (1, sizeof *dfx);
++  if (!dfx)
++    return gpg_error_from_syserror ();
++  dfx->refcount = 1;
++
+   if ( opt.verbose && !dek->algo_info_printed )
+     {
+       const char *s = gcry_cipher_algo_name (dek->algo);
+@@ -77,20 +102,20 @@
+     goto leave;
+   blocksize = gcry_cipher_get_algo_blklen (dek->algo);
+   if ( !blocksize || blocksize > 16 )
+-    log_fatal("unsupported blocksize %u\n", blocksize );
++    log_fatal ("unsupported blocksize %u\n", blocksize );
+   nprefix = blocksize;
+   if ( ed->len && ed->len < (nprefix+2) )
+     BUG();
+ 
+   if ( ed->mdc_method ) 
+     {
+-      if (gcry_md_open (&dfx.mdc_hash, ed->mdc_method, 0 ))
++      if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
+         BUG ();
+       if ( DBG_HASHING )
+-        gcry_md_start_debug (dfx.mdc_hash, "checkmdc");
++        gcry_md_start_debug (dfx->mdc_hash, "checkmdc");
+     }
+ 
+-  rc = gcry_cipher_open (&dfx.cipher_hd, dek->algo,
++  rc = gcry_cipher_open (&dfx->cipher_hd, dek->algo,
+                          GCRY_CIPHER_MODE_CFB,
+                          (GCRY_CIPHER_SECURE
+                           | ((ed->mdc_method || dek->algo >= 100)?
+@@ -104,7 +129,7 @@
+ 
+ 
+   /* log_hexdump( "thekey", dek->key, dek->keylen );*/
+-  rc = gcry_cipher_setkey (dfx.cipher_hd, dek->key, dek->keylen);
++  rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
+   if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
+     {
+       log_info(_("WARNING: message was encrypted with"
+@@ -123,7 +148,7 @@
+       goto leave;
+     }
+ 
+-  gcry_cipher_setiv (dfx.cipher_hd, NULL, 0);
++  gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
+ 
+   if ( ed->len )
+     {
+@@ -144,8 +169,8 @@
+           temp[i] = c;
+     }
+   
+-  gcry_cipher_decrypt (dfx.cipher_hd, temp, nprefix+2, NULL, 0);
+-  gcry_cipher_sync (dfx.cipher_hd);
++  gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
++  gcry_cipher_sync (dfx->cipher_hd);
+   p = temp;
+   /* log_hexdump( "prefix", temp, nprefix+2 ); */
+   if (dek->symmetric
+@@ -155,17 +180,18 @@
+       goto leave;
+     }
+   
+-  if ( dfx.mdc_hash )
+-    gcry_md_write (dfx.mdc_hash, temp, nprefix+2);
+-  
++  if ( dfx->mdc_hash )
++    gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
++
++  dfx->refcount++;
+   if ( ed->mdc_method )
+-    iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
++    iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
+   else
+-    iobuf_push_filter( ed->buf, decode_filter, &dfx );
++    iobuf_push_filter ( ed->buf, decode_filter, dfx );
+ 
+   proc_packets ( procctx, ed->buf );
+   ed->buf = NULL;
+-  if ( ed->mdc_method && dfx.eof_seen == 2 )
++  if ( ed->mdc_method && dfx->eof_seen == 2 )
+     rc = gpg_error (GPG_ERR_INV_PACKET);
+   else if ( ed->mdc_method )
+     { 
+@@ -184,26 +210,28 @@
+          bytes are appended.  */
+       int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
+ 
+-      gcry_cipher_decrypt (dfx.cipher_hd, dfx.defer, 22, NULL, 0);
+-      gcry_md_write (dfx.mdc_hash, dfx.defer, 2);
+-      gcry_md_final (dfx.mdc_hash);
++      assert (dfx->cipher_hd);
++      assert (dfx->mdc_hash);
++      gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
++      gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
++      gcry_md_final (dfx->mdc_hash);
+ 
+-      if (dfx.defer[0] != '\xd3' || dfx.defer[1] != '\x14' )
++      if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' )
+         {
+           log_error("mdc_packet with invalid encoding\n");
+           rc = gpg_error (GPG_ERR_INV_PACKET);
+         }
+       else if (datalen != 20
+-               || memcmp (gcry_md_read (dfx.mdc_hash, 0),dfx.defer+2,datalen))
++               || memcmp (gcry_md_read (dfx->mdc_hash, 0),
++                          dfx->defer+2,datalen ))
+         rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
+-      /* log_printhex("MDC message:", dfx.defer, 22); */
+-      /* log_printhex("MDC calc:", gcry_md_read (dfx.mdc_hash,0), datalen); */
++      /* log_printhex("MDC message:", dfx->defer, 22); */
++      /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
+     }
+   
+   
+  leave:
+-  gcry_cipher_close (dfx.cipher_hd);
+-  gcry_md_close (dfx.mdc_hash);
++  release_dfx_context (dfx);
+   return rc;
+ }
+ 
+@@ -214,7 +242,7 @@
+ mdc_decode_filter (void *opaque, int control, IOBUF a,
+                    byte *buf, size_t *ret_len)
+ {
+-  decode_filter_ctx_t *dfx = opaque;
++  decode_filter_ctx_t dfx = opaque;
+   size_t n, size = *ret_len;
+   int rc = 0;
+   int c;
+@@ -226,11 +254,11 @@
+     }
+   else if( control == IOBUFCTRL_UNDERFLOW )
+     {
+-      assert(a);
+-      assert( size > 44 );
++      assert (a);
++      assert ( size > 44 );
+       
+       /* Get at least 22 bytes and put it somewhere ahead in the buffer. */
+-      for(n=22; n < 44 ; n++ )
++      for (n=22; n < 44 ; n++ )
+         {
+           if( (c = iobuf_get(a)) == -1 )
+             break;
+@@ -279,8 +307,10 @@
+ 
+       if ( n )
+         {
+-          gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
+-          gcry_md_write (dfx->mdc_hash, buf, n);
++          if ( dfx->cipher_hd )
++            gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
++          if ( dfx->mdc_hash )
++            gcry_md_write (dfx->mdc_hash, buf, n);
+ 	}
+       else
+         {
+@@ -289,6 +319,10 @@
+ 	}
+       *ret_len = n;
+     }
++  else if ( control == IOBUFCTRL_FREE ) 
++    {
++      release_dfx_context (dfx);
++    }
+   else if ( control == IOBUFCTRL_DESC ) 
+     {
+       *(char**)buf = "mdc_decode_filter";
+@@ -300,7 +334,7 @@
+ static int
+ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
+ {
+-  decode_filter_ctx_t *fc = opaque;
++  decode_filter_ctx_t fc = opaque;
+   size_t n, size = *ret_len;
+   int rc = 0;
+   
+@@ -311,11 +345,18 @@
+       if ( n == -1 )
+         n = 0;
+       if ( n )
+-        gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
++        {
++          if (fc->cipher_hd)
++            gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
++        }
+       else
+         rc = -1; /* EOF */
+       *ret_len = n;
+     }
++  else if ( control == IOBUFCTRL_FREE ) 
++    {
++      release_dfx_context (fc);
++    }
+   else if ( control == IOBUFCTRL_DESC )
+     {
+       *(char**)buf = "decode_filter";



More information about the CRUX mailing list