Return requested size for malloc_usable_size when MALLOC_CHECK_ > 0

[BZ #1349]

malloc_usable_size returns the usable size in an allocated chunk,
which may be >= the requested size. In the case of MALLOC_CHECK_ being
exported to > 0 however, only the requested size is usable, since a
magic value is written at the end of the request size to trap writes
beyond request bounds. Hence, when MALLOC_CHECK_ is exported to > 0,
malloc_usable_size() should return the request size.
This commit is contained in:
Siddhesh Poyarekar 2012-09-05 21:49:00 +05:30
parent 4d038ae316
commit 6ef9cc37f0
6 changed files with 100 additions and 9 deletions

View file

@ -1,3 +1,13 @@
2012-09-05 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #1349]
* malloc/Makefile (tests): Add tst-malloc-usable test case.
(tst-malloc-usable-ENV): Set environment for test case.
* malloc/hooks.c (malloc_check_get_size): New function to get
requested size.
* malloc/malloc.c (musable): Use malloc_check_get_size.
* malloc/tst-malloc-usable.c: New test case.
2012-09-05 Andreas Schwab <schwab@linux-m68k.org>
* stdlib/tst-strtod-overflow.c (TIMEOUT): Define.

8
NEWS
View file

@ -9,10 +9,10 @@ Version 2.17
* The following bugs are resolved with this release:
3479, 5400, 6778, 6808, 9685, 9914, 11607, 13412, 13717, 13696, 13939,
13966, 14042, 14090, 14166, 14150, 14151, 14154, 14157, 14166, 14173,
14195, 14252, 14283, 14298, 14303, 14307, 14328, 14331, 14336, 14337,
14347, 14349, 14459, 14476, 14505, 14516, 14519, 14532, 14538
1349, 3479, 5400, 6778, 6808, 9685, 9914, 11607, 13412, 13717, 13696,
13939, 13966, 14042, 14090, 14166, 14150, 14151, 14154, 14157, 14166,
14173, 14195, 14252, 14283, 14298, 14303, 14307, 14328, 14331, 14336,
14337, 14347, 14349, 14459, 14476, 14505, 14516, 14519, 14532, 14538
* Support for STT_GNU_IFUNC symbols added for s390 and s390x.
Optimized versions of memcpy, memset, and memcmp added for System z10 and

View file

@ -1,5 +1,4 @@
# Copyright (C) 1991-2003, 2005, 2006, 2007, 2009, 2011, 2012
# Free Software Foundation, Inc.
# Copyright (C) 1991-2012 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@ -26,7 +25,7 @@ all:
dist-headers := malloc.h
headers := $(dist-headers) obstack.h mcheck.h
tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
tst-mallocstate tst-mcheck tst-mallocfork tst-trim1
tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 tst-malloc-usable
test-srcs = tst-mtrace
routines = malloc morecore mcheck mtrace obstack
@ -116,6 +115,7 @@ endif
endif
tst-mcheck-ENV = MALLOC_CHECK_=3
tst-malloc-usable-ENV = MALLOC_CHECK_=3
CPPFLAGS-malloc.c += -DPER_THREAD
# Uncomment this for test releases. For public releases it is too expensive.

View file

@ -1,5 +1,5 @@
/* Malloc implementation for multiple threads without lock contention.
Copyright (C) 2001-2009, 2011, 2012 Free Software Foundation, Inc.
Copyright (C) 2001-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
@ -89,6 +89,35 @@ __malloc_check_init()
#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. */
static size_t
malloc_check_get_size(mchunkptr p)
{
size_t 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;
size -= c) {
if(c<=0 || size<(c+2*SIZE_SZ)) {
malloc_printerr(check_action, "malloc_check_get_size: memory corruption",
chunk2mem(p));
return 0;
}
}
/* chunk2mem size. */
return size - 2*SIZE_SZ;
}
/* Instrument a chunk with overrun detector byte(s) and convert it
into a user pointer with requested size sz. */

View file

@ -1,5 +1,5 @@
/* Malloc implementation for multiple threads without lock contention.
Copyright (C) 1996-2009, 2010, 2011, 2012 Free Software Foundation, Inc.
Copyright (C) 1996-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Wolfram Gloger <wg@malloc.de>
and Doug Lea <dl@cs.oswego.edu>, 2001.
@ -4563,6 +4563,9 @@ musable(void* mem)
mchunkptr p;
if (mem != 0) {
p = mem2chunk(mem);
if (__builtin_expect(using_malloc_checking == 1, 0))
return malloc_check_get_size(p);
if (chunk_is_mmapped(p))
return chunksize(p) - 2*SIZE_SZ;
else if (inuse(p))

View file

@ -0,0 +1,49 @@
/* Ensure that malloc_usable_size returns the request size with
MALLOC_CHECK_ exported to a positive value.
Copyright (C) 2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <malloc.h>
#include <string.h>
#include <stdio.h>
static int
do_test (void)
{
size_t usable_size;
void *p = malloc (7);
if (!p)
{
printf ("memory allocation failed\n");
return 1;
}
usable_size = malloc_usable_size (p);
if (usable_size != 7)
{
printf ("malloc_usable_size: expected 7 but got %zu\n", usable_size);
return 1;
}
memset (p, 0, usable_size);
free (p);
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"