Sophie

Sophie

distrib > Mandriva > 2010.2 > x86_64 > by-pkgid > e0ecf1de97625bd665ba6741f8b282d6 > files > 42

glibc-2.11.1-8mnb2.src.rpm

commit 29d138d26f3a4c65d0916892371ca1af26102b79
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Jan 22 12:41:12 2010 -0800

    regexec.c: avoid overflow in realloc buffer length computation
    (cherry picked from commit aef699dce14a56ff0f212f533e5ea485d3cec96a)

commit a8e15c34fcef7eac14b431f0d0aa79162180b423
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Jan 22 12:33:58 2010 -0800

    regexec.c: avoid leaks on out-of-memory failure paths
    (cherry picked from commit 74bc9f14db655d2fdc9018d396af326e9b9bdf3f)

commit f13891f2e60093d435a14f09a3ed60090d156e25
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Jan 22 12:22:18 2010 -0800

    regexec.c: avoid overflow in computing sum of lengths
    (cherry picked from commit 42a2c9b5c3c92f7e2f556d7bc9dc80e557484574)

commit ce4929787c15c85a000e432b82d02dd0f45a21fa
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Jan 22 12:15:53 2010 -0800

    re_search_internal: Avoid overflow in computing re_malloc buffer size
    (cherry picked from commit eadc09f22cd81dd0153fba0fd8514261ea9b4196)

commit 815460ad9b99f6e7cb65b0d8285973abd23de3b1
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Jan 22 12:03:56 2010 -0800

    prune_impossible_nodes: Avoid overflow in computing re_malloc buffer size
    (cherry picked from commit 4cd028677b55c8be454bb06f0b28a8b41beffe9b)

commit 6b6e4661ec78d763dcad0b059e29b03b0abd2cb4
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Jan 22 10:52:38 2010 -0800

    regexec.c: avoid arithmetic overflow in buffer size calculation
    (cherry picked from commit daa8454919de6c4e8b914c5d45276abd20baab08)

commit 9a395a890e199fa29cb7a9f9d5cb62caa3e20332
Author: Paul Eggert <eggert@cs.ucla.edu>
Date:   Fri Jan 22 10:39:59 2010 -0800

    regexec.c: simplify re_search_2_stub
    (cherry picked from commit d044d844dd011bb26317ac36da2d22ebe19621b1)

commit fcadae915dc0bb6b8071857c510c7356ce8fc0ca
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Fri Jan 22 10:22:53 2010 -0800

    Simplify test in re_string_skip_chars.
    (cherry picked from commit 5ddf954cf19d43f54ba44f487427d210952e1236)

commit 78e4576784342c9c5d16dbf55789f5c332fa0379
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Fri Jan 22 10:17:45 2010 -0800

    regex_internal.c: don't assume WEOF fits in wchar_t
    (cherry picked from commit 4f08104cbf07d87a42c389f2af17f87c445e59d5)

commit 6537ebd97f63c3aeebd954137e799d53a43bb69c
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Fri Jan 22 09:57:30 2010 -0800

    regex_internal.c: remove useless variable and the code to set it.
    (cherry picked from commit 0dae5d4ec1740b511af97c600df1ceea37ada73d)

commit b1b5d0f7786d02f49ff4569f80573b48a0240a2e
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Fri Jan 22 09:48:35 2010 -0800

    Extend overflow detection in re_dfa_add_node.
    (cherry picked from commit 22364644882b6cf426ed13be5b6480c3a9210eb1)

commit 791a72bc4bae0c29f725694d629872dba81c50e2
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Fri Jan 22 09:33:01 2010 -0800

    regex: avoid internal re_realloc overflow
    
    (adjusted cherry-pick from 54dd0ab31fe2b2168ba1a6180a0c05941fb54b3c)

---
 ChangeLog              |   53 ++++++++++++++++++++++++++++++++++++++++++++++
 posix/regex_internal.c |   34 +++++++++++++++++++----------
 posix/regexec.c        |   55 +++++++++++++++++++++++++++++++++++++----------
 3 files changed, 118 insertions(+), 24 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 30480e2..2223015 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2010-01-22  Jim Meyering  <jim@meyering.net>
+
+	[BZ #11193]
+	* posix/regexec.c (extend_buffers): Avoid overflow in realloc
+	buffer length computation.
+
+	[BZ #11192]
+	* posix/regexec.c (re_copy_regs): Don't leak when allocation
+	of the start buffer succeeds but allocation of the "end" one fails.
+
+	[BZ #11191]
+	* posix/regexec.c (re_search_2_stub): Check for overflow
+	when adding the sizes of the two strings.
+
+	[BZ #11190]
+	* posix/regexec.c (re_search_internal): Avoid overflow
+	in computing re_malloc buffer size.
+
+	[BZ #11189]
+	* posix/regexec.c (prune_impossible_nodes): Avoid overflow
+	in computing re_malloc buffer size.
+
+	[BZ #11188]
+	* posix/regexec.c (build_trtable): Avoid arithmetic overflow
+	in size calculation.
+
+	[BZ #11187]
+	* posix/regexec.c (re_search_2_stub): Use simpler method than
+	boolean for freeing internal storage.
+
+2010-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* posix/regex_internal.c (re_string_skip_chars): Simplify test for
+	failed mbrtowc call.
+
+2010-01-22  Jim Meyering  <jim@meyering.net>
+
+	[BZ #11186]
+	* posix/regex_internal.c (re_string_skip_chars): Don't assume WEOF
+	fits in wchar_t.  Problem reported by Eric Blake.
+
+	[BZ #11185]
+	* posix/regex_internal.c (re_string_reconstruct): Remove declaration
+	and stores into set-but-not-used local, "q".
+
+	[BZ #11184]
+	* posix/regex_internal.c (re_dfa_add_node): Extend the overflow
+	detection test.  Patch by Paul Eggert.
+
+	[BZ #11183]
+	* posix/regex_internal.c (re_string_realloc_buffers):
+	Detect and handle internal overflow.  Patch by Paul Eggert
+
 2010-01-19  Ulrich Drepper  <drepper@redhat.com>
 
 	[BZ #11194]
diff --git a/posix/regex_internal.c b/posix/regex_internal.c
index ff28e5f..8183a29 100644
--- a/posix/regex_internal.c
+++ b/posix/regex_internal.c
@@ -133,7 +133,14 @@ re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
 #ifdef RE_ENABLE_I18N
   if (pstr->mb_cur_max > 1)
     {
-      wint_t *new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
+      wint_t *new_wcs;
+
+      /* Avoid overflow in realloc.  */
+      const size_t max_object_size = MAX (sizeof (wint_t), sizeof (int));
+      if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
+	return REG_ESPACE;
+
+      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
       if (BE (new_wcs == NULL, 0))
 	return REG_ESPACE;
       pstr->wcs = new_wcs;
@@ -482,18 +489,18 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
   mbstate_t prev_st;
   int rawbuf_idx;
   size_t mbclen;
-  wchar_t wc = WEOF;
+  wint_t wc = WEOF;
 
   /* Skip the characters which are not necessary to check.  */
   for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
        rawbuf_idx < new_raw_idx;)
     {
-      int remain_len;
-      remain_len = pstr->len - rawbuf_idx;
+      wchar_t wc2;
+      int remain_len = pstr->len - rawbuf_idx;
       prev_st = pstr->cur_state;
-      mbclen = __mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx,
+      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
 			  remain_len, &pstr->cur_state);
-      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
+      if (BE ((ssize_t) mbclen <= 0, 0))
 	{
 	  /* We treat these cases as a single byte character.  */
 	  if (mbclen == 0 || remain_len == 0)
@@ -503,10 +510,12 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
 	  mbclen = 1;
 	  pstr->cur_state = prev_st;
 	}
+      else
+	wc = (wint_t) wc2;
       /* Then proceed the next character.  */
       rawbuf_idx += mbclen;
     }
-  *last_wc = (wint_t) wc;
+  *last_wc = wc;
   return rawbuf_idx;
 }
 #endif /* RE_ENABLE_I18N  */
@@ -694,7 +703,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
 
 	      if (pstr->is_utf8)
 		{
-		  const unsigned char *raw, *p, *q, *end;
+		  const unsigned char *raw, *p, *end;
 
 		  /* Special case UTF-8.  Multi-byte chars start with any
 		     byte other than 0x80 - 0xbf.  */
@@ -723,13 +732,11 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
 			  unsigned char buf[6];
 			  size_t mbclen;
 
-			  q = p;
 			  if (BE (pstr->trans != NULL, 0))
 			    {
 			      int i = mlen < 6 ? mlen : 6;
 			      while (--i >= 0)
 				buf[i] = pstr->trans[p[i]];
-			      q = buf;
 			    }
 			  /* XXX Don't use mbrtowc, we know which conversion
 			     to use (UTF-8 -> UCS4).  */
@@ -1404,8 +1411,11 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
       re_node_set *new_edests, *new_eclosures;
       re_token_t *new_nodes;
 
-      /* Avoid overflows.  */
-      if (BE (new_nodes_alloc < dfa->nodes_alloc, 0))
+      /* Avoid overflows in realloc.  */
+      const size_t max_object_size = MAX (sizeof (re_token_t),
+					  MAX (sizeof (re_node_set),
+					       sizeof (int)));
+      if (BE (SIZE_MAX / max_object_size < new_nodes_alloc, 0))
 	return -1;
 
       new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
diff --git a/posix/regexec.c b/posix/regexec.c
index b8db740..f877016 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -368,16 +368,16 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
   const char *str;
   int rval;
   int len = length1 + length2;
-  int free_str = 0;
+  char *s = NULL;
 
-  if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
+  if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
     return -2;
 
   /* Concatenate the strings.  */
   if (length2 > 0)
     if (length1 > 0)
       {
-	char *s = re_malloc (char, len);
+	s = re_malloc (char, len);
 
 	if (BE (s == NULL, 0))
 	  return -2;
@@ -388,17 +388,14 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
 	memcpy (s + length1, string2, length2);
 #endif
 	str = s;
-	free_str = 1;
       }
     else
       str = string2;
   else
     str = string1;
 
-  rval = re_search_stub (bufp, str, len, start, range, stop, regs,
-			 ret_len);
-  if (free_str)
-    re_free ((char *) str);
+  rval = re_search_stub (bufp, str, len, start, range, stop, regs, ret_len);
+  re_free (s);
   return rval;
 }
 
@@ -512,9 +509,14 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
   if (regs_allocated == REGS_UNALLOCATED)
     { /* No.  So allocate them with malloc.  */
       regs->start = re_malloc (regoff_t, need_regs);
-      regs->end = re_malloc (regoff_t, need_regs);
-      if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0))
+      if (BE (regs->start == NULL, 0))
 	return REGS_UNALLOCATED;
+      regs->end = re_malloc (regoff_t, need_regs);
+      if (BE (regs->end == NULL, 0))
+	{
+	  re_free (regs->start);
+	  return REGS_UNALLOCATED;
+	}
       regs->num_regs = need_regs;
     }
   else if (regs_allocated == REGS_REALLOCATE)
@@ -524,9 +526,15 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
       if (BE (need_regs > regs->num_regs, 0))
 	{
 	  regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
-	  regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs);
-	  if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
+	  regoff_t *new_end;
+	  if (BE (new_start == NULL, 0))
 	    return REGS_UNALLOCATED;
+	  new_end = re_realloc (regs->end, regoff_t, need_regs);
+	  if (BE (new_end == NULL, 0))
+	    {
+	      re_free (new_start);
+	      return REGS_UNALLOCATED;
+	    }
 	  regs->start = new_start;
 	  regs->end = new_end;
 	  regs->num_regs = need_regs;
@@ -694,6 +702,13 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
      multi character collating element.  */
   if (nmatch > 1 || dfa->has_mb_node)
     {
+      /* Avoid overflow.  */
+      if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0))
+	{
+	  err = REG_ESPACE;
+	  goto free_return;
+	}
+
       mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
       if (BE (mctx.state_log == NULL, 0))
 	{
@@ -952,6 +967,11 @@ prune_impossible_nodes (mctx)
 #endif
   match_last = mctx->match_last;
   halt_node = mctx->last_node;
+
+  /* Avoid overflow.  */
+  if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0))
+    return REG_ESPACE;
+
   sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
   if (BE (sifted_states == NULL, 0))
     {
@@ -3362,6 +3382,13 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
   if (BE (err != REG_NOERROR, 0))
     goto out_free;
 
+  /* Avoid arithmetic overflow in size calculation.  */
+  if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
+	    / (3 * sizeof (re_dfastate_t *)))
+	   < ndests),
+	  0))
+    goto out_free;
+
   if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
 			 + ndests * 3 * sizeof (re_dfastate_t *)))
     dest_states = (re_dfastate_t **)
@@ -4077,6 +4104,10 @@ extend_buffers (re_match_context_t *mctx)
   reg_errcode_t ret;
   re_string_t *pstr = &mctx->input;
 
+  /* Avoid overflow.  */
+  if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
+    return REG_ESPACE;
+
   /* Double the lengthes of the buffers.  */
   ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
   if (BE (ret != REG_NOERROR, 0))