Your message dated Fri, 8 Dec 2006 00:33:12 -0200
with message-id <[EMAIL PROTECTED]>
and subject line fixed in 1.4.6-1 upload
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: gnupg
Version: 1.4.5-3
Severity: grave
Tags: security upstream

From: Werner Koch <[EMAIL PROTECTED]>
Subject: [Announce] GnuPG: remotely controllable function pointer 
[CVE-2006-6235]
To: [EMAIL PROTECTED], [email protected]
Date: Wed, 06 Dec 2006 16:55:52 +0100

     GnuPG: remotely controllable function pointer [CVE-2006-6235]
    ===============================================================
                              2006-12-04

Summary
=======

Tavis Ormandy of the Gentoo security team identified a severe and
exploitable bug in the processing of encrypted packets in GnuPG.

[ Please do not send private mail in response to this message.  The
  mailing list gnupg-devel is the best place to discuss this problem
  (please subscribe first so you don't need moderator approval [1]). ]


Impact
======

Using malformed OpenPGP packets an attacker is able to modify and
dereference a function pointer in GnuPG.  This is a remotely
exploitable bug and affects any use of GnuPG where an attacker can
control the data processed by GnuPG.  It is not necessary limited to
encrypted data, also signed data may be affected.

Affected versions: All versions of GnuPG   < 1.4.6 
                   All versions of GnuPG-2 < 2.0.2
                   All beta versions of GnuPG-2 (1.9.0 .. 1.9.95)
Affected tools: gpg, gpgv, gpg2 and gpgv2.
Affected platforms: All.

gpg-agent, gpgsm as well as other tools are not affected.

A workaround is not known. 

[...]

This is a patch against GnuPG 1.4.5.  Change the directory to g10/ and
apply this patch.

2006-12-02  Werner Koch  <[EMAIL PROTECTED]>

        * encr-data.c: Allocate DFX context on the heap and not on the
        stack.  Changes at several places.  Fixes CVE-2006-6235.
        


--- encr-data.c.orig    2006-05-16 14:34:26.000000000 +0200
+++ encr-data.c 2006-12-04 11:58:53.000000000 +0100
@@ -44,7 +44,27 @@ typedef struct {
     char defer[20];
     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 )
+    {
+      cipher_close (dfx->cipher_hd);
+      dfx->cipher_hd = NULL;
+      md_close (dfx->mdc_hash);
+      dfx->mdc_hash = NULL;
+      xfree (dfx);
+    }
+}
 
 
 /****************
@@ -60,7 +80,10 @@ decrypt_data( void *procctx, PKT_encrypt
     unsigned blocksize;
     unsigned nprefix;
 
-    memset( &dfx, 0, sizeof dfx );
+
+    dfx = xcalloc (1, sizeof *dfx);
+    dfx->refcount = 1;
+
     if( opt.verbose && !dek->algo_info_printed ) {
        const char *s = cipher_algo_to_string( dek->algo );
        if( s )
@@ -79,15 +102,15 @@ decrypt_data( void *procctx, PKT_encrypt
        BUG();
 
     if( ed->mdc_method ) {
-       dfx.mdc_hash = md_open( ed->mdc_method, 0 );
+       dfx->mdc_hash = md_open ( ed->mdc_method, 0 );
        if ( DBG_HASHING )
-           md_start_debug(dfx.mdc_hash, "checkmdc");
+           md_start_debug (dfx->mdc_hash, "checkmdc");
     }
-    dfx.cipher_hd = cipher_open( dek->algo,
-                                ed->mdc_method? CIPHER_MODE_CFB
-                                              : CIPHER_MODE_AUTO_CFB, 1 );
+    dfx->cipher_hd = cipher_open ( dek->algo,
+                                   ed->mdc_method? CIPHER_MODE_CFB
+                                                 : CIPHER_MODE_AUTO_CFB, 1 );
     /* log_hexdump( "thekey", dek->key, dek->keylen );*/
-    rc = cipher_setkey( dfx.cipher_hd, dek->key, dek->keylen );
+    rc = cipher_setkey ( dfx->cipher_hd, dek->key, dek->keylen );
     if( rc == G10ERR_WEAK_KEY )
       {
        log_info(_("WARNING: message was encrypted with"
@@ -105,7 +128,7 @@ decrypt_data( void *procctx, PKT_encrypt
         goto leave;
     }
 
-    cipher_setiv( dfx.cipher_hd, NULL, 0 );
+    cipher_setiv ( dfx->cipher_hd, NULL, 0 );
 
     if( ed->len ) {
        for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) {
@@ -122,8 +145,8 @@ decrypt_data( void *procctx, PKT_encrypt
            else
                temp[i] = c;
     }
-    cipher_decrypt( dfx.cipher_hd, temp, temp, nprefix+2);
-    cipher_sync( dfx.cipher_hd );
+    cipher_decrypt ( dfx->cipher_hd, temp, temp, nprefix+2);
+    cipher_sync ( dfx->cipher_hd );
     p = temp;
 /* log_hexdump( "prefix", temp, nprefix+2 ); */
     if(dek->symmetric
@@ -133,34 +156,34 @@ decrypt_data( void *procctx, PKT_encrypt
        goto leave;
       }
 
-    if( dfx.mdc_hash )
-       md_write( dfx.mdc_hash, temp, nprefix+2 );
+    if ( dfx->mdc_hash )
+       md_write ( dfx->mdc_hash, temp, nprefix+2 );
 
-    if( ed->mdc_method )
-       iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx );
+    dfx->refcount++;
+    if ( ed->mdc_method )
+       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 = G10ERR_INVALID_PACKET;
     else if( ed->mdc_method ) { /* check the mdc */
        int datalen = md_digest_length( ed->mdc_method );
 
-       cipher_decrypt( dfx.cipher_hd, dfx.defer, dfx.defer, 20);
-       md_final( dfx.mdc_hash );
+       cipher_decrypt ( dfx->cipher_hd, dfx->defer, dfx->defer, 20);
+       md_final ( dfx->mdc_hash );
        if( datalen != 20
-           || memcmp(md_read( dfx.mdc_hash, 0 ), dfx.defer, datalen) )
+           || memcmp(md_read( dfx->mdc_hash, 0 ), dfx->defer, datalen) )
            rc = G10ERR_BAD_SIGN;
-       /*log_hexdump("MDC calculated:", md_read( dfx.mdc_hash, 0), datalen);*/
-       /*log_hexdump("MDC message   :", dfx.defer, 20);*/
+       /*log_hexdump("MDC calculated:",md_read( dfx->mdc_hash, 0), datalen);*/
+       /*log_hexdump("MDC message   :", dfx->defer, 20);*/
     }
     
 
   leave:
-    cipher_close(dfx.cipher_hd);
-    md_close( dfx.mdc_hash );
+    release_dfx_context (dfx);
     return rc;
 }
 
@@ -171,7 +194,7 @@ static int
 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,8 +249,10 @@ mdc_decode_filter( void *opaque, int con
        }
 
        if( n ) {
-           cipher_decrypt( dfx->cipher_hd, buf, buf, n);
-           md_write( dfx->mdc_hash, buf, n );
+            if (dfx->cipher_hd)
+                cipher_decrypt( dfx->cipher_hd, buf, buf, n);
+            if (dfx->mdc_hash)
+                md_write( dfx->mdc_hash, buf, n );
        }
        else {
            assert( dfx->eof_seen );
@@ -235,6 +260,9 @@ mdc_decode_filter( void *opaque, int con
        }
        *ret_len = n;
     }
+    else if ( control == IOBUFCTRL_FREE ) {
+        release_dfx_context (dfx);
+    }
     else if( control == IOBUFCTRL_DESC ) {
        *(char**)buf = "mdc_decode_filter";
     }
@@ -244,7 +272,7 @@ mdc_decode_filter( void *opaque, int con
 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;
 
@@ -252,12 +280,17 @@ decode_filter( void *opaque, int control
        assert(a);
        n = iobuf_read( a, buf, size );
        if( n == -1 ) n = 0;
-       if( n )
-           cipher_decrypt( fc->cipher_hd, buf, buf, n);
+       if( n ) {
+            if (fc->cipher_hd)
+                cipher_decrypt( fc->cipher_hd, buf, buf, n);
+        }
        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";
     }



--- End Message ---
--- Begin Message ---
Version: 1.4.6-1

This bug has been fixed by the following upload to unstable; it remains open
in stable:

gnupg (1.4.6-1) unstable; urgency=high

  * New upstream release.
   * Fixes remotely controllable function pointer [CVE-2006-6235]

  * 27_filename_overflow.dpatch: merged upstream, dropped.
  * 24_gpgv_manpage_cleanup.dpatch: updated and a couple of additional
    trivial fixes.

  * debian/rules (binary-arch): info copy of manuals moved to
    /usr/share/info - remove them there instead.  Manuals are now built
    from texi source, so install them from build tree, not top level.

  * debian/copyright: update to add OpenSSL exemption for keyserver helper
    tools.

 -- James Troup <[EMAIL PROTECTED]>  Thu,  7 Dec 2006 02:54:51 +0000


-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

--- End Message ---

Reply via email to