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