about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--NEWS1
-rw-r--r--malloc/malloc.c43
3 files changed, 9 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index 043e589364..4295c42db9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-12-31  Florian Weimer  <fw@deneb.enyo.de>
+
+	[BZ #24027]
+	* malloc/malloc.c (_int_realloc): Always call memcpy for the
+	copying operation.  (ncopies had the wrong type, resulting in an
+	integer wraparound and too few elements being copied.)
+
 2018-09-06  Stefan Liebler  <stli@linux.ibm.com>
 
 	* sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
diff --git a/NEWS b/NEWS
index abe90d1422..ac22222a7c 100644
--- a/NEWS
+++ b/NEWS
@@ -85,6 +85,7 @@ The following bugs are resolved with this release:
   [22715] x86-64: Properly align La_x86_64_retval to VEC_SIZE
   [22774] malloc: Integer overflow in malloc (CVE-2018-6551)
   [23538] pthread_cond_broadcast: Fix waiters-after-spinning case
+  [24027] malloc: Integer overflow in realloc
 
 Version 2.25
 
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 0686e5de8e..5cbdaef863 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -4250,11 +4250,6 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
   mchunkptr        bck;             /* misc temp for linking */
   mchunkptr        fwd;             /* misc temp for linking */
 
-  unsigned long    copysize;        /* bytes to copy */
-  unsigned int     ncopies;         /* INTERNAL_SIZE_T words to copy */
-  INTERNAL_SIZE_T* s;               /* copy source */
-  INTERNAL_SIZE_T* d;               /* copy destination */
-
   const char *errstr = NULL;
 
   /* oldmem size */
@@ -4332,43 +4327,7 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T oldsize,
             }
           else
             {
-              /*
-                 Unroll copy of <= 36 bytes (72 if 8byte sizes)
-                 We know that contents have an odd number of
-                 INTERNAL_SIZE_T-sized words; minimally 3.
-               */
-
-              copysize = oldsize - SIZE_SZ;
-              s = (INTERNAL_SIZE_T *) (chunk2mem (oldp));
-              d = (INTERNAL_SIZE_T *) (newmem);
-              ncopies = copysize / sizeof (INTERNAL_SIZE_T);
-              assert (ncopies >= 3);
-
-              if (ncopies > 9)
-                memcpy (d, s, copysize);
-
-              else
-                {
-                  *(d + 0) = *(s + 0);
-                  *(d + 1) = *(s + 1);
-                  *(d + 2) = *(s + 2);
-                  if (ncopies > 4)
-                    {
-                      *(d + 3) = *(s + 3);
-                      *(d + 4) = *(s + 4);
-                      if (ncopies > 6)
-                        {
-                          *(d + 5) = *(s + 5);
-                          *(d + 6) = *(s + 6);
-                          if (ncopies > 8)
-                            {
-                              *(d + 7) = *(s + 7);
-                              *(d + 8) = *(s + 8);
-                            }
-                        }
-                    }
-                }
-
+	      memcpy (newmem, chunk2mem (oldp), oldsize - SIZE_SZ);
               _int_free (av, oldp, 1);
               check_inuse_chunk (av, newp);
               return chunk2mem (newp);