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], info-gnu@gnu.org
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";
     }



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to