arrfab / rpms / glibc

Forked from rpms/glibc 5 years ago
Clone

Blame SOURCES/glibc-rh1348000.patch

147e83
From 265cbed8e73b23e3b38ada6cc42482c53a216224 Mon Sep 17 00:00:00 2001
147e83
From: James Lemke <jwlemke@codesourcery.com>
147e83
Date: Tue, 19 May 2015 12:10:26 -0700
147e83
Subject: [PATCH] Fix for test "malloc_usable_size: expected 7 but got 11"
147e83
147e83
[BZ #17581] The checking chain of unused chunks was terminated by a hash of
147e83
    the block pointer, which was sometimes confused with the chunk length byte.
147e83
    We now avoid using a length byte equal to the magic byte.
147e83
147e83
147e83
diff -rup a/malloc/hooks.c b/malloc/hooks.c
147e83
--- a/malloc/hooks.c	2017-08-01 16:19:28.000000000 -0400
147e83
+++ b/malloc/hooks.c	2017-08-01 16:42:23.651295223 -0400
147e83
@@ -87,11 +87,22 @@ __malloc_check_init()
147e83
    overruns.  The goal here is to avoid obscure crashes due to invalid
147e83
    usage, unlike in the MALLOC_DEBUG code. */
147e83
 
147e83
-#define MAGICBYTE(p) ( ( ((size_t)p >> 3) ^ ((size_t)p >> 11)) & 0xFF )
147e83
+static unsigned char
147e83
+magicbyte (const void *p)
147e83
+{
147e83
+  unsigned char magic;
147e83
+
147e83
+  magic = (((uintptr_t) p >> 3) ^ ((uintptr_t) p >> 11)) & 0xFF;
147e83
+  /* Do not return 1.  See the comment in mem2mem_check().  */
147e83
+  if (magic == 1)
147e83
+    ++magic;
147e83
+  return magic;
147e83
+}
147e83
+
147e83
 
147e83
-/* Visualize the chunk as being partitioned into blocks of 256 bytes from the
147e83
-   highest address of the chunk, downwards.  The beginning of each block tells
147e83
-   us the size of the previous block, up to the actual size of the requested
147e83
+/* Visualize the chunk as being partitioned into blocks of 255 bytes from the
147e83
+   highest address of the chunk, downwards.  The end of each block tells
147e83
+   us the size of that block, up to the actual size of the requested
147e83
    memory.  Our magic byte is right at the end of the requested size, so we
147e83
    must reach it with this iteration, otherwise we have witnessed a memory
147e83
    corruption.  */
147e83
@@ -100,7 +111,7 @@ malloc_check_get_size(mchunkptr p)
147e83
 {
147e83
   size_t size;
147e83
   unsigned char c;
147e83
-  unsigned char magic = MAGICBYTE(p);
147e83
+  unsigned char magic = magicbyte (p);
147e83
 
147e83
   assert(using_malloc_checking == 1);
147e83
 
147e83
@@ -120,29 +131,35 @@ malloc_check_get_size(mchunkptr p)
147e83
 }
147e83
 
147e83
 /* Instrument a chunk with overrun detector byte(s) and convert it
147e83
-   into a user pointer with requested size sz. */
147e83
+   into a user pointer with requested size req_sz. */
147e83
 
147e83
 static void*
147e83
 internal_function
147e83
-mem2mem_check(void *ptr, size_t sz)
147e83
+mem2mem_check(void *ptr, size_t req_sz)
147e83
 {
147e83
   mchunkptr p;
147e83
   unsigned char* m_ptr = ptr;
147e83
-  size_t i;
147e83
+  size_t max_sz, block_sz, i;
147e83
+  unsigned char magic;
147e83
 
147e83
   if (!ptr)
147e83
     return ptr;
147e83
   p = mem2chunk(ptr);
147e83
-  for(i = chunksize(p) - (chunk_is_mmapped(p) ? 2*SIZE_SZ+1 : SIZE_SZ+1);
147e83
-      i > sz;
147e83
-      i -= 0xFF) {
147e83
-    if(i-sz < 0x100) {
147e83
-      m_ptr[i] = (unsigned char)(i-sz);
147e83
-      break;
147e83
+  magic = magicbyte (p);
147e83
+  max_sz = chunksize (p) - 2 * SIZE_SZ;
147e83
+  if (!chunk_is_mmapped (p))
147e83
+    max_sz += SIZE_SZ;
147e83
+  for (i = max_sz - 1; i > req_sz; i -= block_sz)
147e83
+    {
147e83
+      block_sz = MIN (i - req_sz, 0xff);
147e83
+      /* Don't allow the magic byte to appear in the chain of length bytes.
147e83
+         For the following to work, magicbyte cannot return 0x01.  */
147e83
+      if (block_sz == magic)
147e83
+        --block_sz;
147e83
+
147e83
+      m_ptr[i] = block_sz;
147e83
     }
147e83
-    m_ptr[i] = 0xFF;
147e83
-  }
147e83
-  m_ptr[sz] = MAGICBYTE(p);
147e83
+  m_ptr[req_sz] = magic;
147e83
   return (void*)m_ptr;
147e83
 }
147e83
 
147e83
@@ -159,10 +176,11 @@ mem2chunk_check(void* mem, unsigned char
147e83
 
147e83
   if(!aligned_OK(mem)) return NULL;
147e83
   p = mem2chunk(mem);
147e83
+  sz = chunksize (p);
147e83
+  magic = magicbyte (p);
147e83
   if (!chunk_is_mmapped(p)) {
147e83
     /* Must be a chunk in conventional heap memory. */
147e83
     int contig = contiguous(&main_arena);
147e83
-    sz = chunksize(p);
147e83
     if((contig &&
147e83
 	((char*)p
147e83
 	 ((char*)p + sz)>=(mp_.sbrk_base+main_arena.system_mem) )) ||
147e83
@@ -171,9 +189,9 @@ mem2chunk_check(void* mem, unsigned char
147e83
 			    (contig && (char*)prev_chunk(p)
147e83
 			    next_chunk(prev_chunk(p))!=p) ))
147e83
       return NULL;
147e83
-    magic = MAGICBYTE(p);
147e83
     for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
147e83
-      if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
147e83
+      if(c == 0 || sz < (c + 2 * SIZE_SZ))
147e83
+	return NULL;
147e83
     }
147e83
   } else {
147e83
     unsigned long offset, page_mask = GLRO(dl_pagesize)-1;
147e83
@@ -188,11 +206,12 @@ mem2chunk_check(void* mem, unsigned char
147e83
 	offset<0x2000) ||
147e83
        !chunk_is_mmapped(p) || (p->size & PREV_INUSE) ||
147e83
        ( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) ||
147e83
-       ( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) )
147e83
+       ((p->prev_size + sz) & page_mask) != 0)
147e83
       return NULL;
147e83
-    magic = MAGICBYTE(p);
147e83
+
147e83
     for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
147e83
-      if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
147e83
+      if(c == 0 || sz < (c + 2 * SIZE_SZ))
147e83
+	return NULL;
147e83
     }
147e83
   }
147e83
   ((unsigned char*)p)[sz] ^= 0xFF;