This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.20-284-g08f1e1d


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  08f1e1d2bca9ef087813357780ec0bafe71c7d29 (commit)
      from  a8a7d7d212de1dd8c8d0a59eb9ea1c9289f63be1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=08f1e1d2bca9ef087813357780ec0bafe71c7d29

commit 08f1e1d2bca9ef087813357780ec0bafe71c7d29
Author: James Lemke <jwlemke@codesourcery.com>
Date:   Wed Nov 26 13:45:24 2014 -0800

    Fix for test "malloc_usable_size: expected 7 but got 11"
    
    [BZ #17581] The checking chain of unused chunks was terminated by a hash of
    the block pointer, which was sometimes confused with the chunk length byte.
    The chain is now terminated by a NULL byte.

diff --git a/ChangeLog b/ChangeLog
index 613f304..7d58833 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-12-01  James Lemke  <jwlemke@codesourcery.com>
+
+	[BZ #17581]
+	* malloc/hooks.c
+	(mem2mem_check): Add a terminator to the chain of checking blocks.
+	(malloc_check_get_size): Use it here.
+	(mem2chunk_check): Ditto.
+
 2014-12-01  Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/strtok.S: New file.
diff --git a/NEWS b/NEWS
index e1f2342..5450e8e 100644
--- a/NEWS
+++ b/NEWS
@@ -12,8 +12,8 @@ Version 2.21
   6652, 12926, 13862, 14132, 14138, 14171, 14498, 15215, 15884, 16469,
   16619, 16740, 16857, 17192, 17266, 17344, 17363, 17370, 17371, 17411,
   17460, 17475, 17485, 17501, 17506, 17508, 17522, 17555, 17570, 17571,
-  17572, 17573, 17574, 17582, 17583, 17584, 17585, 17589, 17594, 17608,
-  17616, 17625, 17633.
+  17572, 17573, 17574, 17581, 17582, 17583, 17584, 17585, 17589, 17594,
+  17608, 17616, 17625, 17633.
 
 * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
   under certain input conditions resulting in the execution of a shell for
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 00ee6be..996111a 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -90,31 +90,35 @@ __malloc_check_init (void)
 
 #define MAGICBYTE(p) ((((size_t) p >> 3) ^ ((size_t) p >> 11)) & 0xFF)
 
-/* Visualize the chunk as being partitioned into blocks of 256 bytes from the
-   highest address of the chunk, downwards.  The beginning of each block tells
-   us the size of the previous block, up to the actual size of the requested
-   memory.  Our magic byte is right at the end of the requested size, so we
-   must reach it with this iteration, otherwise we have witnessed a memory
-   corruption.  */
+/* Visualize the chunk as being partitioned into blocks of 255 bytes from the
+   highest address of the chunk, downwards.  The end of each block tells us
+   the size of that block, up to the actual size of the requested memory.
+   The last block has a length of zero and is followed by the magic byte.
+   Our magic byte is right at the end of the requested size.  If we don't
+   reach it with this iteration we have witnessed a memory corruption.  */
 static size_t
 malloc_check_get_size (mchunkptr p)
 {
-  size_t size;
+  size_t total_sz, size;
   unsigned char c;
   unsigned char magic = MAGICBYTE (p);
 
   assert (using_malloc_checking == 1);
 
-  for (size = chunksize (p) - 1 + (chunk_is_mmapped (p) ? 0 : SIZE_SZ);
-       (c = ((unsigned char *) p)[size]) != magic;
+  /* Validate the length-byte chain.  */
+  total_sz = chunksize (p) + (chunk_is_mmapped (p) ? 0 : SIZE_SZ);
+  for (size = total_sz - 1;
+       (c = ((unsigned char *) p)[size]) != 0;
        size -= c)
     {
-      if (c <= 0 || size < (c + 2 * SIZE_SZ))
-        {
-          malloc_printerr (check_action, "malloc_check_get_size: memory corruption",
-                           chunk2mem (p));
-          return 0;
-        }
+      if (size <= c + 2 * SIZE_SZ)
+	break;
+    }
+  if (c != 0 || ((unsigned char *) p)[--size] != magic)
+    {
+      malloc_printerr (check_action, "malloc_check_get_size: memory corruption",
+		       chunk2mem (p));
+      return 0;
     }
 
   /* chunk2mem size.  */
@@ -130,22 +134,24 @@ mem2mem_check (void *ptr, size_t sz)
 {
   mchunkptr p;
   unsigned char *m_ptr = ptr;
-  size_t i;
+  size_t user_sz, block_sz, i;
 
   if (!ptr)
     return ptr;
 
   p = mem2chunk (ptr);
-  for (i = chunksize (p) - (chunk_is_mmapped (p) ? 2 * SIZE_SZ + 1 : SIZE_SZ + 1);
-       i > sz;
-       i -= 0xFF)
+  user_sz = chunksize (p) + (chunk_is_mmapped (p) ? 0 : SIZE_SZ);
+  user_sz -= 2 * SIZE_SZ;
+  for (i = user_sz - 1; i > sz; i -= block_sz)
     {
-      if (i - sz < 0x100)
-        {
-          m_ptr[i] = (unsigned char) (i - sz);
-          break;
-        }
-      m_ptr[i] = 0xFF;
+      block_sz = i - (sz + 1);
+      if (block_sz > 0xff)
+	block_sz = 0xff;
+
+      m_ptr[i] = (unsigned char) block_sz;
+
+      if (block_sz == 0)
+	break;
     }
   m_ptr[sz] = MAGICBYTE (p);
   return (void *) m_ptr;
@@ -166,11 +172,12 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
     return NULL;
 
   p = mem2chunk (mem);
+  sz = chunksize (p);
+  magic = MAGICBYTE (p);
   if (!chunk_is_mmapped (p))
     {
       /* Must be a chunk in conventional heap memory. */
       int contig = contiguous (&main_arena);
-      sz = chunksize (p);
       if ((contig &&
            ((char *) p < mp_.sbrk_base ||
             ((char *) p + sz) >= (mp_.sbrk_base + main_arena.system_mem))) ||
@@ -180,12 +187,13 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
                                next_chunk (prev_chunk (p)) != p)))
         return NULL;
 
-      magic = MAGICBYTE (p);
-      for (sz += SIZE_SZ - 1; (c = ((unsigned char *) p)[sz]) != magic; sz -= c)
+      for (sz += SIZE_SZ - 1; (c = ((unsigned char *) p)[sz]) != 0; sz -= c)
         {
-          if (c <= 0 || sz < (c + 2 * SIZE_SZ))
-            return NULL;
+	  if (sz <= c + 2 * SIZE_SZ)
+	    break;
         }
+      if (c != 0 || ((unsigned char *) p)[--sz] != magic)
+	return NULL;
     }
   else
     {
@@ -201,15 +209,16 @@ mem2chunk_check (void *mem, unsigned char **magic_p)
            offset < 0x2000) ||
           !chunk_is_mmapped (p) || (p->size & PREV_INUSE) ||
           ((((unsigned long) p - p->prev_size) & page_mask) != 0) ||
-          ((sz = chunksize (p)), ((p->prev_size + sz) & page_mask) != 0))
+          ((p->prev_size + sz) & page_mask) != 0)
         return NULL;
 
-      magic = MAGICBYTE (p);
-      for (sz -= 1; (c = ((unsigned char *) p)[sz]) != magic; sz -= c)
+      for (sz -= 1; (c = ((unsigned char *) p)[sz]) != 0; sz -= c)
         {
-          if (c <= 0 || sz < (c + 2 * SIZE_SZ))
-            return NULL;
+	  if (sz <= c + 2 * SIZE_SZ)
+	    break;
         }
+      if (c != 0 || ((unsigned char *) p)[--sz] != magic)
+	return NULL;
     }
   ((unsigned char *) p)[sz] ^= 0xFF;
   if (magic_p)

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog      |    8 +++++
 NEWS           |    4 +-
 malloc/hooks.c |   79 +++++++++++++++++++++++++++++++------------------------
 3 files changed, 54 insertions(+), 37 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]