[svn] gcry - r1157 - in trunk: . cipher src

svn author wk cvs at cvs.gnupg.org
Wed Jun 21 11:19:15 CEST 2006


Author: wk
Date: 2006-06-21 11:19:13 +0200 (Wed, 21 Jun 2006)
New Revision: 1157

Modified:
   trunk/NEWS
   trunk/TODO
   trunk/cipher/ChangeLog
   trunk/cipher/md.c
   trunk/cipher/pubkey.c
   trunk/cipher/rsa.c
   trunk/src/ChangeLog
   trunk/src/global.c
   trunk/src/sexp.c
Log:
Changed xmalloc style calls to proper malloc calls with error returns at
many (but not all) places.


Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/NEWS	2006-06-21 09:19:13 UTC (rev 1157)
@@ -18,6 +18,9 @@
 gcry_pk_algo_name       CHANGED (minor change in respect to return value)
 gcry_cipher_algo_name   CHANGED (minor change in respect to return value)
 GCRY_MD_SHA224          NEW
+GCRY_PK_USAGE_CERT      NEW
+GCRY_PK_USAGE_AUTH      NEW
+GCRY_PK_USAGE_UNKN      NEW
 
 FIXME: Please add API changes immediatley so that we don't
        forget about them.

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/TODO	2006-06-21 09:19:13 UTC (rev 1157)
@@ -48,3 +48,14 @@
   initialization of the pool and in case the entropy collectros need
   to run that bunch of Unix utilities we don't waste their precious
   results.
+
+* Out of memory handler for secure memory shopuld do proper logging
+
+  There is no shortage of standard memory, so logging is most likely
+  possible.
+
+* signed vs. unsigned.
+  Sync the code with 1.2 where we have fixed all these issues.
+
+
+

Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/cipher/ChangeLog	2006-06-21 09:19:13 UTC (rev 1157)
@@ -1,3 +1,11 @@
+2006-06-21  Werner Koch  <wk at g10code.com>
+
+	* rsa.c (_gcry_rsa_generate): Replace xcalloc by calloc.
+	* pubkey.c (gcry_pk_encrypt, gcry_pk_sign): Ditto.
+	(sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_encrypt) 
+	(gcry_pk_sign, gcry_pk_genkey, gcry_pk_get_keygrip): Ditto. 
+	* md.c (md_copy): Ditto.
+	
 2006-04-22  Moritz Schulte  <moritz at g10code.com>
 
 	* random-daemon.c (_gcry_daemon_initialize_basics): New argument:

Modified: trunk/cipher/md.c
===================================================================
--- trunk/cipher/md.c	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/cipher/md.c	2006-06-21 09:19:13 UTC (rev 1157)
@@ -440,8 +440,8 @@
 	  }
 	  if (! ctx->macpads)
 	    {
+	      err = gpg_err_code_from_errno (errno);
 	      md_close (hd);
-	      err = gpg_err_code_from_errno (errno);
 	    }
 	}
     }
@@ -602,8 +602,8 @@
 	  b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
 	  if (! b->macpads)
 	    {
+	      err = gpg_err_code_from_errno (errno);
 	      md_close (bhd);
-	      err = gpg_err_code_from_errno (errno);
 	    }
 	  else
 	    memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
@@ -612,32 +612,41 @@
 
   /* Copy the complete list of algorithms.  The copied list is
      reversed, but that doesn't matter. */
-  if (! err)
-    for (ar = a->list; ar; ar = ar->next)
-      {
-	if (a->secure)
-	  br = gcry_xmalloc_secure (sizeof *br
-				    + ar->digest->contextsize
-				    - sizeof(ar->context));
-	else
-	  br = gcry_xmalloc (sizeof *br
-			     + ar->digest->contextsize
-			     - sizeof (ar->context));
-	memcpy (br, ar,
-		sizeof (*br) + ar->digest->contextsize - sizeof (ar->context));
-	br->next = b->list;
-	b->list = br;
+  if (!err)
+    {
+      for (ar = a->list; ar; ar = ar->next)
+        {
+          if (a->secure)
+            br = gcry_malloc_secure (sizeof *br
+                                     + ar->digest->contextsize
+                                     - sizeof(ar->context));
+          else
+            br = gcry_malloc (sizeof *br
+                              + ar->digest->contextsize
+                              - sizeof (ar->context));
+          if (!br)
+            {
+	      err = gpg_err_code_from_errno (errno);
+              md_close (bhd);
+              break;
+            }
 
-	/* Add a reference to the module.  */
-	ath_mutex_lock (&digests_registered_lock);
-	_gcry_module_use (br->module);
-	ath_mutex_unlock (&digests_registered_lock);
-       }
+          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
+                           - sizeof (ar->context)));
+          br->next = b->list;
+          b->list = br;
+          
+          /* Add a reference to the module.  */
+          ath_mutex_lock (&digests_registered_lock);
+          _gcry_module_use (br->module);
+          ath_mutex_unlock (&digests_registered_lock);
+        }
+    }
 
-  if (a->debug)
+  if (a->debug && !err)
     md_start_debug (bhd, "unknown");
 
-  if (! err)
+  if (!err)
     *b_hd = bhd;
 
   return err;
@@ -822,7 +831,7 @@
       rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
       break;
     case GCRYCTL_START_DUMP:
-      md_start_debug (hd, buffer);
+      md_start_debug (hd, (char*)buffer);
       break;
     case GCRYCTL_STOP_DUMP:
       md_stop_debug( hd );

Modified: trunk/cipher/pubkey.c
===================================================================
--- trunk/cipher/pubkey.c	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/cipher/pubkey.c	2006-06-21 09:19:13 UTC (rev 1157)
@@ -786,7 +786,15 @@
     }
 
     {
-      char *name_terminated = gcry_xmalloc (n + 1);
+      char *name_terminated;
+
+      name_terminated = gcry_malloc (n + 1);
+      if (!name_terminated)
+        {
+          err = gpg_err_code_from_errno (errno);
+          gcry_sexp_release (list);
+          return err;
+        }
       memcpy (name_terminated, name, n);
       name_terminated[n] = 0;
 
@@ -876,7 +884,17 @@
     }
       
     {
-      char *name_terminated = gcry_xmalloc (n + 1);
+      char *name_terminated;
+
+      name_terminated = gcry_malloc (n + 1);
+      if (!name_terminated)
+        {
+          err = gcry_err_code_from_errno (errno);
+	  gcry_sexp_release (l2);
+	  gcry_sexp_release (list);
+          return err;
+        }
+          
       memcpy (name_terminated, name, n);
       name_terminated[n] = 0;
       
@@ -1026,7 +1044,14 @@
     }
 
   {
-    char *name_terminated = gcry_xmalloc (n + 1);
+    char *name_terminated;
+
+    name_terminated = gcry_malloc (n + 1);
+    if (!name_terminated)
+      {
+        err = gcry_err_code_from_errno (errno);
+        goto leave;
+      }
     memcpy (name_terminated, name, n);
     name_terminated[n] = 0;
     
@@ -1391,7 +1416,12 @@
     goto leave;
 
   /* Now we can encrypt DATA to CIPH. */
-  ciph = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*ciph));
+  ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
+  if (!ciph)
+    {
+      rc = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
   mpi_free (data);
   data = NULL;
@@ -1407,7 +1437,12 @@
     void **arg_list;
     
     /* Build the string.  */
-    string = p = gcry_xmalloc (needed);
+    string = p = gcry_malloc (needed);
+    if (!string)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
     p = stpcpy ( p, "(enc-val(" );
     p = stpcpy ( p, algo_name );
     for (i=0; algo_elems[i]; i++ )
@@ -1609,7 +1644,12 @@
   if (rc)
     goto leave;
 
-  result = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*result));
+  result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
+  if (!result)
+    {
+      rc = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
   rc = pubkey_sign (module->mod_id, result, hash, skey);
   if (rc)
     goto leave;
@@ -1625,7 +1665,12 @@
     needed += 10 * nelem;
 
     /* Build the string. */
-    string = p = gcry_xmalloc (needed);
+    string = p = gcry_malloc (needed);
+    if (!string)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
     p = stpcpy (p, "(sig-val(");
     p = stpcpy (p, algo_name);
     for (i = 0; algo_elems[i]; i++)
@@ -1847,7 +1892,12 @@
       goto leave;
     }
 
-  name_terminated = gcry_xmalloc (n + 1);
+  name_terminated = gcry_malloc (n + 1);
+  if (!name_terminated)
+    {
+      rc = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
   memcpy (name_terminated, name, n);
   name_terminated[n] = 0;
   ath_mutex_lock (&pubkeys_registered_lock);
@@ -1908,7 +1958,12 @@
       goto leave;
     }
   
-  name_terminated = gcry_xmalloc (n + 1);
+  name_terminated = gcry_malloc (n + 1);
+  if (!name_terminated)
+    {
+      rc = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
   memcpy (name_terminated, name, n);
   name_terminated[n] = 0;
   nbits = (unsigned int) strtoul (name_terminated, NULL, 0);
@@ -1935,7 +1990,12 @@
 
     /* Build the string. */
     nelem = 0;
-    string = p = gcry_xmalloc (needed);
+    string = p = gcry_malloc (needed);
+    if (!string)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
+      }
     p = stpcpy (p, "(key-data");
     p = stpcpy (p, "(public-key(");
     p = stpcpy (p, algo_name);
@@ -2103,7 +2163,9 @@
     goto fail; /* Invalid structure of object. */
 
   {
-    char *name_terminated = gcry_xmalloc (n + 1);
+    char *name_terminated = gcry_malloc (n + 1);
+    if (!name_terminated)
+      goto fail;
     memcpy (name_terminated, name, n);
     name_terminated[n] = 0;
     ath_mutex_lock (&pubkeys_registered_lock);

Modified: trunk/cipher/rsa.c
===================================================================
--- trunk/cipher/rsa.c	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/cipher/rsa.c	2006-06-21 09:19:13 UTC (rev 1157)
@@ -28,6 +28,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
+
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
@@ -440,6 +442,8 @@
                     gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
   RSA_secret_key sk;
+  gpg_err_code_t rc;
+  int i;
 
   generate (&sk, nbits, use_e);
   skey[0] = sk.n;
@@ -449,10 +453,21 @@
   skey[4] = sk.q;
   skey[5] = sk.u;
   
-  /* make an empty list of factors */
-  *retfactors = gcry_xcalloc( 1, sizeof **retfactors );
+  /* Make an empty list of factors.  */
+  *retfactors = gcry_calloc ( 1, sizeof **retfactors );
+  if (!*retfactors)
+    {
+      rc = gpg_err_code_from_errno (errno);
+      for (i=0; i <= 5; i++)
+        {
+          gcry_mpi_release (skey[i]);
+          skey[i] = NULL;
+        }
+    }
+  else
+    rc = 0;
   
-  return GPG_ERR_NO_ERROR;
+  return rc;
 }
 
 

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/src/ChangeLog	2006-06-21 09:19:13 UTC (rev 1157)
@@ -1,3 +1,17 @@
+2006-06-21  Werner Koch  <wk at g10code.com>
+
+	* global.c (gcry_xcalloc, gcry_xcalloc_secure): Made safe against
+	integer overflow.
+
+	* sexp.c (make_space): Return an error on out of core.
+	(sexp_sscan): Remove all xmalloc style calls and return proper
+	error codes on allocation failures.
+	(gcry_sexp_find_token): Ditto.
+	(gcry_sexp_nth): 
+	
+	* sexp.c (gcry_sexp_find_token): Re-indented and removed a cruft
+	"while(level);" which fortunately had no effect.
+
 2006-04-28  Werner Koch  <wk at g10code.com>
 
 	* gcrypt.h (GCRY_MD_SHA224): Change value from 306 to 11 to match

Modified: trunk/src/global.c
===================================================================
--- trunk/src/global.c	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/src/global.c	2006-06-21 09:19:13 UTC (rev 1157)
@@ -1,6 +1,6 @@
 /* global.c  -	global control functions
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- *               2004, 2005  Free Software Foundation, Inc.
+ *               2004, 2005, 2006  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -659,20 +659,41 @@
     return p;
 }
 
+
 void *
 gcry_xcalloc( size_t n, size_t m )
 {
-    void *p = gcry_xmalloc( n*m );
-    memset( p, 0, n*m );
-    return p;
+  size_t nbytes;
+  void *p;
+
+  nbytes = n * m; 
+  if (m && nbytes / m != n) 
+    {
+      errno = ENOMEM;
+      _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+    }
+
+  p = gcry_xmalloc ( nbytes );
+  memset ( p, 0, nbytes );
+  return p;
 }
 
 void *
 gcry_xcalloc_secure( size_t n, size_t m )
 {
-    void *p = gcry_xmalloc_secure( n* m );
-    memset( p, 0, n*m );
-    return p;
+  size_t nbytes;
+  void *p;
+
+  nbytes = n * m; 
+  if (m && nbytes / m != n) 
+    {
+      errno = ENOMEM;
+      _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+    }
+
+  p = gcry_xmalloc_secure ( nbytes );
+  memset ( p, 0, nbytes );
+  return p;
 }
 
 char *

Modified: trunk/src/sexp.c
===================================================================
--- trunk/src/sexp.c	2006-06-21 09:16:02 UTC (rev 1156)
+++ trunk/src/sexp.c	2006-06-21 09:19:13 UTC (rev 1157)
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <ctype.h>
+#include <errno.h>
 
 #define GCRYPT_NO_MPI_MACROS 1
 #include "g10lib.h"
@@ -367,61 +368,78 @@
 gcry_sexp_t
 gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
 {
-    const byte *p;
-    DATALEN n;
+  const byte *p;
+  DATALEN n;
+  
+  if ( !list )
+    return NULL;
 
-    if ( !list )
-	return NULL;
+  if ( !toklen )
+    toklen = strlen(tok);
 
-    if( !toklen )
-	toklen = strlen(tok);
-    p = list->d;
-    while ( *p != ST_STOP ) {
-	if ( *p == ST_OPEN && p[1] == ST_DATA ) {
-	    const byte *head = p;
+  p = list->d;
+  while ( *p != ST_STOP )
+    {
+      if ( *p == ST_OPEN && p[1] == ST_DATA ) 
+        {
+          const byte *head = p;
 
-	    p += 2;
-	    memcpy ( &n, p, sizeof n ); p += sizeof n;
-	    if ( n == toklen && !memcmp( p, tok, toklen ) ) { /* found it */
-		gcry_sexp_t newlist;
-		byte *d;
-		int level = 1;
+          p += 2;
+          memcpy ( &n, p, sizeof n );
+          p += sizeof n;
+          if ( n == toklen && !memcmp( p, tok, toklen ) )
+            { /* found it */
+              gcry_sexp_t newlist;
+              byte *d;
+              int level = 1;
 
-		/* look for the end of the list */
-		for ( p += n; level; p++ ) {
-		    if ( *p == ST_DATA ) {
+              /* Look for the end of the list.  */
+              for ( p += n; level; p++ ) 
+                {
+                  if ( *p == ST_DATA )
+                    {
 			memcpy ( &n, ++p, sizeof n );
 			p += sizeof n + n;
-			p--; /* compensate for later increment */
+			p--; /* Compensate for later increment. */
 		    }
-		    else if ( *p == ST_OPEN ) {
-			level++;
+                  else if ( *p == ST_OPEN ) 
+                    {
+                      level++;
 		    }
-		    else if ( *p == ST_CLOSE ) {
-			level--;
+                  else if ( *p == ST_CLOSE ) 
+                    {
+                      level--;
 		    }
-		    else if ( *p == ST_STOP ) {
-			BUG ();
+                  else if ( *p == ST_STOP ) 
+                    {
+                      BUG ();
 		    }
-		} while ( level );
-		n = p - head;
+		}
+              n = p - head;
 
-		newlist = gcry_xmalloc ( sizeof *newlist + n );
-		d = newlist->d;
-		memcpy ( d, head, n ); d += n;
-		*d++ = ST_STOP;
-		return normalize ( newlist );
+              newlist = gcry_malloc ( sizeof *newlist + n );
+              if (!newlist)
+                {
+                  /* No way to return an error code, so we can only
+                     return Not Found. */
+                  return NULL;
+                }
+              d = newlist->d;
+              memcpy ( d, head, n ); d += n;
+              *d++ = ST_STOP;
+              return normalize ( newlist );
 	    }
-	    p += n;
+          p += n;
 	}
-	else if ( *p == ST_DATA ) {
-	    memcpy ( &n, ++p, sizeof n ); p += sizeof n;
-	    p += n;
+      else if ( *p == ST_DATA )
+        {
+          memcpy ( &n, ++p, sizeof n ); p += sizeof n;
+          p += n;
 	}
-	else
-	    p++;
+      else
+        p++;
     }
-    return NULL;
+  return NULL;
 }
 
 /****************
@@ -462,9 +480,8 @@
 
 
 
-/****************
- * Extract the CAR of the given list
- */
+/* Extract the CAR of the given list.  May return NULL for bad lists
+   or memory failure.  */
 gcry_sexp_t
 gcry_sexp_nth( const gcry_sexp_t list, int number )
 {
@@ -503,7 +520,9 @@
 
     if ( *p == ST_DATA ) {
 	memcpy ( &n, p, sizeof n ); p += sizeof n;
-	newlist = gcry_xmalloc ( sizeof *newlist + n + 1 );
+	newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+        if (!newlist)
+          return NULL;
 	d = newlist->d;
 	memcpy ( d, p, n ); d += n;
 	*d++ = ST_STOP;
@@ -531,7 +550,9 @@
 	} while ( level );
 	n = p + 1 - head;
 
-	newlist = gcry_xmalloc ( sizeof *newlist + n );
+	newlist = gcry_malloc ( sizeof *newlist + n );
+        if (!newlist)
+          return NULL;
 	d = newlist->d;
 	memcpy ( d, head, n ); d += n;
 	*d++ = ST_STOP;
@@ -723,7 +744,9 @@
     } while ( level );
     n = p - head;
 
-    newlist = gcry_xmalloc ( sizeof *newlist + n + 2 );
+    newlist = gcry_malloc ( sizeof *newlist + n + 2 );
+    if (!newlist)
+      return NULL;
     d = newlist->d;
     *d++ = ST_OPEN;
     memcpy ( d, head, n ); d += n;
@@ -775,21 +798,29 @@
     byte *pos;
 };
 
-static void
+static gpg_err_code_t
 make_space ( struct make_space_ctx *c, size_t n )
 {
-    size_t used = c->pos - c->sexp->d;
-
-    if ( used + n + sizeof(DATALEN) + 1 >= c->allocated ) {
-	gcry_sexp_t newsexp;
-	byte *newhead;
-
-	c->allocated += 2*(n+sizeof(DATALEN)+1);
-	newsexp = gcry_xrealloc ( c->sexp, sizeof *newsexp + c->allocated - 1 );
-	newhead = newsexp->d;
-	c->pos = newhead + used;
-	c->sexp = newsexp;
+  size_t used = c->pos - c->sexp->d;
+  
+  if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
+    {
+      gcry_sexp_t newsexp;
+      byte *newhead;
+      size_t newsize;
+      
+      newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
+      if (newsize <= c->allocated)
+        return GPG_ERR_TOO_LARGE;
+      newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
+      if (!newsexp)
+        return gpg_err_code_from_errno (errno);
+      c->allocated = newsize;
+      newhead = newsexp->d;
+      c->pos = newhead + used;
+      c->sexp = newsexp;
     }
+  return 0;
 }
 
 
@@ -891,7 +922,7 @@
 	    const char *buffer, size_t length, int argflag,
 	    va_list arg_ptr, void **arg_list)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t err = 0;
   static const char tokenchars[] =
     "abcdefghijklmnopqrstuvwxyz"
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -913,8 +944,6 @@
   int arg_counter = 0;
   int level = 0;
 
-  /* FIXME: invent better error codes (?).  */
-
   if (!erroff)
     erroff = &dummy_erroff;
 
@@ -931,21 +960,41 @@
     }                                                    \
   while (0)
 
-#define MAKE_SPACE(n)  do { make_space ( &c, (n) ); } while (0)
+  /* The MAKE_SPACE macro is used before each store operation to
+     ensure that the buffer is large enough.  It requires a global
+     context named C and jumps out to the label LEAVE on error! It
+     also sets ERROFF using the variables BUFFER and P.  */
+#define MAKE_SPACE(n)  do {                                                \
+                            gpg_err_code_t _ms_err = make_space (&c, (n)); \
+                            if (_ms_err)                                   \
+                              {                                            \
+                                err = _ms_err;                             \
+                                *erroff = p - buffer;                      \
+                                goto leave;                                \
+                              }                                            \
+                       } while (0)
+
+  /* The STORE_LEN macro is used to store the length N at buffer P. */
 #define STORE_LEN(p,n) do {						   \
 			    DATALEN ashort = (n);			   \
 			    memcpy ( (p), &ashort, sizeof(ashort) );	   \
 			    (p) += sizeof (ashort);			   \
 			} while (0)
 
-  /* We assume that the internal representation takes less memory
-   * than the provided one.  However, we add space for one extra datalen
-   * so that the code which does the ST_CLOSE can use MAKE_SPACE */
+  /* We assume that the internal representation takes less memory than
+     the provided one.  However, we add space for one extra datalen so
+     that the code which does the ST_CLOSE can use MAKE_SPACE */
   c.allocated = length + sizeof(DATALEN);
   if (buffer && length && gcry_is_secure (buffer))
-    c.sexp = gcry_xmalloc_secure (sizeof *c.sexp + c.allocated - 1);
+    c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
   else
-    c.sexp = gcry_xmalloc (sizeof *c.sexp + c.allocated - 1);
+    c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
+  if (!c.sexp)
+    {
+      err = gpg_err_code_from_errno (errno);
+      *erroff = 0;
+      goto leave;
+    }
   c.pos = c.sexp->d;
 
   for (p = buffer, n = length; n; p++, n--)
@@ -986,6 +1035,7 @@
 		      *erroff = p - buffer;
 		      /* Invalid octal value.  */
 		      err = GPG_ERR_SEXP_BAD_QUOTATION;
+                      goto leave;
 		    }
 		  p += 2;
 		  n -= 2;
@@ -998,6 +1048,7 @@
 		      *erroff = p - buffer;
 		      /* Invalid hex value.  */
 		      err = GPG_ERR_SEXP_BAD_QUOTATION;
+                      goto leave;
 		    }
 		  p += 2;
 		  n -= 2;
@@ -1028,6 +1079,7 @@
 		  *erroff = p - buffer;
 		  /* Invalid quoted string escape.  */
 		  err = GPG_ERR_SEXP_BAD_QUOTATION;
+                  goto leave;
 		}
 	    }
 	  else if (*p == '\\')
@@ -1060,6 +1112,7 @@
 		{
 		  *erroff = p - buffer;
 		  err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
+                  goto leave;
 		}
 
 	      datalen = hexcount / 2;
@@ -1079,6 +1132,7 @@
 	    {
 	      *erroff = p - buffer;
 	      err = GPG_ERR_SEXP_BAD_HEX_CHAR;
+              goto leave;
 	    }
 	}
       else if (base64)
@@ -1099,6 +1153,7 @@
 		  *erroff = p - buffer;
 		  /* Buffer too short.  */
 		  err = GPG_ERR_SEXP_STRING_TOO_LONG;
+                  goto leave;
 		}
 	      /* Make a new list entry.  */
 	      MAKE_SPACE (datalen);
@@ -1130,6 +1185,7 @@
 	    {
 	      *erroff = p - buffer;
 	      err = GPG_ERR_SEXP_INV_LEN_SPEC;
+              goto leave;
 	    }
 	}
       else if (percent)
@@ -1153,8 +1209,13 @@
 		  gcry_sexp_t newsexp;
 		  byte *newhead;
 
-		  newsexp = gcry_xmalloc_secure (sizeof *newsexp
-						 + c.allocated - 1);
+		  newsexp = gcry_malloc_secure (sizeof *newsexp
+                                                + c.allocated - 1);
+                  if (!newsexp)
+                    {
+                      err = gpg_err_code_from_errno (errno);
+                      goto leave;
+                    }
 		  newhead = newsexp->d;
 		  memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
 		  c.pos = newhead + (c.pos - c.sexp->d);
@@ -1201,8 +1262,13 @@
 		  gcry_sexp_t newsexp;
 		  byte *newhead;
 
-		  newsexp = gcry_xmalloc_secure (sizeof *newsexp
- 						 + c.allocated - 1);
+		  newsexp = gcry_malloc_secure (sizeof *newsexp
+                                                + c.allocated - 1);
+                  if (!newsexp)
+                    {
+                      err = gpg_err_code_from_errno (errno);
+                      goto leave;
+                    }
 		  newhead = newsexp->d;
 		  memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
 		  c.pos = newhead + (c.pos - c.sexp->d);
@@ -1236,6 +1302,7 @@
 	      *erroff = p - buffer;
 	      /* Invalid format specifier.  */
 	      err = GPG_ERR_SEXP_INV_LEN_SPEC;
+              goto leave;
 	    }
 	  percent = NULL;
 	}
@@ -1246,6 +1313,7 @@
 	      *erroff = p - buffer;
 	      /* Open display hint.  */
 	      err = GPG_ERR_SEXP_UNMATCHED_DH;
+              goto leave;
 	    }
 	  MAKE_SPACE (0);
 	  *c.pos++ = ST_OPEN;
@@ -1259,6 +1327,7 @@
 	      *erroff = p - buffer;
 	      /* Open display hint.  */
 	      err = GPG_ERR_SEXP_UNMATCHED_DH;
+              goto leave;
 	    }
 	  MAKE_SPACE (0);
 	  *c.pos++ = ST_CLOSE;
@@ -1283,6 +1352,7 @@
 	      *erroff = p - buffer;
 	      /* Open display hint.  */
 	      err = GPG_ERR_SEXP_NESTED_DH;
+              goto leave;
 	    }
 	  disphint = p;
 	}
@@ -1293,6 +1363,7 @@
 	      *erroff = p - buffer;
 	      /* Open display hint.  */
 	      err = GPG_ERR_SEXP_UNMATCHED_DH;
+              goto leave;
 	    }
 	  disphint = NULL;
 	}
@@ -1303,6 +1374,7 @@
 	      /* A length may not begin with zero.  */
 	      *erroff = p - buffer;
 	      err = GPG_ERR_SEXP_ZERO_PREFIX;
+              goto leave;
 	    }
 	  digptr = p;
 	}
@@ -1318,12 +1390,14 @@
 	     need to save it.  Great.  */
 	  *erroff = p - buffer;
 	  err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+          goto leave;
 	}
       else if (strchr ("&\\", *p))
 	{
 	  /* Reserved punctuation.  */
 	  *erroff = p - buffer;
 	  err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+          goto leave;
 	}
       else if (argflag && (*p == '%'))
 	percent = p;
@@ -1332,14 +1406,16 @@
 	  /* Bad or unavailable.  */
 	  *erroff = p - buffer;
 	  err = GPG_ERR_SEXP_BAD_CHARACTER;
+          goto leave;
 	}
     }
   MAKE_SPACE (0);
   *c.pos++ = ST_STOP;
 
-  if (level)
+  if (level && !err)
     err = GPG_ERR_SEXP_UNMATCHED_PAREN;
 
+ leave:
   if (err)
     {
       /* Error -> deallocate.  */




More information about the Gnupg-commits mailing list