mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 01:51:29 +00:00
Ensure VALGRIND_MALLOCLIKE_BLOCK protects the red zones.
* Redzones for custom alloc were not protected by VALGRIND_MALLOCLIKE_BLOCK. mc_main.c client request handling completed with protection of the redzones. * custom_alloc.c test modified to test this case. * mc_errors.c modified so as to first search for a malloc-ed block bracketting the error : for a custom allocator, a recently freed block can have just been re-allocated. In such a case, describing the address (e.g. in case of error) points to the block freed rather than to the block just allocated. If there is *also* a recently freed block bracketting the address, the block description is changed to indicate that. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12439
This commit is contained in:
parent
6fe6c23808
commit
825fdcf3cb
4
NEWS
4
NEWS
@ -22,6 +22,10 @@ Release 3.8.0 (????)
|
||||
- Addition of GDB server monitor command 'who_points_at' that lists
|
||||
the locations pointing at a block.
|
||||
|
||||
- if a redzone size > 0 is given, VALGRIND_MALLOCLIKE_BLOCK now
|
||||
will detect an invalid access of these redzones, by marking them
|
||||
noaccess.
|
||||
|
||||
* ==================== OTHER CHANGES ====================
|
||||
|
||||
* The C++ demangler has been updated so as to work well with C++
|
||||
|
||||
@ -1115,6 +1115,30 @@ static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
|
||||
if (mempool_block_maybe_describe( a, ai )) {
|
||||
return;
|
||||
}
|
||||
/* Blocks allocated by memcheck malloc functions are either
|
||||
on the recently freed list or on the malloc-ed list.
|
||||
Custom blocks can be on both : a recently freed block might
|
||||
have been just re-allocated.
|
||||
So, first search the malloc-ed block, as the most recent
|
||||
block is the probable cause of error.
|
||||
We however detect and report that this is a recently re-allocated
|
||||
block. */
|
||||
/* -- Search for a currently malloc'd block which might bracket it. -- */
|
||||
VG_(HT_ResetIter)(MC_(malloc_list));
|
||||
while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
|
||||
if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
|
||||
ai->tag = Addr_Block;
|
||||
ai->Addr.Block.block_kind = Block_Mallocd;
|
||||
if (MC_(get_freed_block_bracketting)( a ))
|
||||
ai->Addr.Block.block_desc = "recently re-allocated block";
|
||||
else
|
||||
ai->Addr.Block.block_desc = "block";
|
||||
ai->Addr.Block.block_szB = mc->szB;
|
||||
ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
|
||||
ai->Addr.Block.lastchange = mc->where;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* -- Search for a recently freed block which might bracket it. -- */
|
||||
mc = MC_(get_freed_block_bracketting)( a );
|
||||
if (mc) {
|
||||
@ -1126,19 +1150,6 @@ static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
|
||||
ai->Addr.Block.lastchange = mc->where;
|
||||
return;
|
||||
}
|
||||
/* -- Search for a currently malloc'd block which might bracket it. -- */
|
||||
VG_(HT_ResetIter)(MC_(malloc_list));
|
||||
while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
|
||||
if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
|
||||
ai->tag = Addr_Block;
|
||||
ai->Addr.Block.block_kind = Block_Mallocd;
|
||||
ai->Addr.Block.block_desc = "block";
|
||||
ai->Addr.Block.block_szB = mc->szB;
|
||||
ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
|
||||
ai->Addr.Block.lastchange = mc->where;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* -- Perhaps the variable type/location data describes it? -- */
|
||||
ai->Addr.Variable.descr1
|
||||
= VG_(newXA)( VG_(malloc), "mc.da.descr1",
|
||||
|
||||
@ -5553,11 +5553,15 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
|
||||
case VG_USERREQ__MALLOCLIKE_BLOCK: {
|
||||
Addr p = (Addr)arg[1];
|
||||
SizeT sizeB = arg[2];
|
||||
//UInt rzB = arg[3]; XXX: unused!
|
||||
UInt rzB = arg[3];
|
||||
Bool is_zeroed = (Bool)arg[4];
|
||||
|
||||
MC_(new_block) ( tid, p, sizeB, /*ignored*/0, is_zeroed,
|
||||
MC_AllocCustom, MC_(malloc_list) );
|
||||
if (rzB > 0) {
|
||||
MC_(make_mem_noaccess) ( p - rzB, rzB);
|
||||
MC_(make_mem_noaccess) ( p + sizeB, rzB);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
case VG_USERREQ__RESIZEINPLACE_BLOCK: {
|
||||
|
||||
@ -54,6 +54,44 @@ static void custom_free(void* p)
|
||||
VALGRIND_FREELIKE_BLOCK( p, RZ );
|
||||
}
|
||||
|
||||
static void checkredzone(void)
|
||||
{
|
||||
/* check that accessing the redzone of a MALLOCLIKE block
|
||||
is detected when the superblock was not marked as no access. */
|
||||
char superblock[1 + RZ + 20 + RZ + 1];
|
||||
char *p = 1 + RZ + superblock;
|
||||
assert(RZ > 0);
|
||||
|
||||
// Indicate we have allocated p from our superblock:
|
||||
VALGRIND_MALLOCLIKE_BLOCK( p, 20, RZ, /*is_zeroed*/1 );
|
||||
p[0] = 0;
|
||||
p[-1] = p[0]; // error expected
|
||||
p[-RZ] = p[0]; // error expected
|
||||
p[-RZ-1] = p[0]; // no error expected
|
||||
|
||||
p[19] = 0;
|
||||
p[19 + 1] = p[0]; // error expected
|
||||
p[19 + RZ] = p[0]; // error expected
|
||||
p[19 + RZ + 1] = p[0]; // no error expected
|
||||
|
||||
VALGRIND_FREELIKE_BLOCK( p, RZ );
|
||||
|
||||
// Now, indicate we have re-allocated p from our superblock
|
||||
// but with only a size 10.
|
||||
VALGRIND_MALLOCLIKE_BLOCK( p, 10, RZ, /*is_zeroed*/1 );
|
||||
p[0] = 0;
|
||||
p[-1] = p[0]; // error expected
|
||||
p[-RZ] = p[0]; // error expected
|
||||
p[-RZ-1] = p[0]; // no error expected
|
||||
|
||||
p[9] = 0;
|
||||
p[9 + 1] = p[0]; // error expected
|
||||
p[9 + RZ] = p[0]; // error expected
|
||||
p[9 + RZ + 1] = p[0]; // no error expected
|
||||
|
||||
VALGRIND_FREELIKE_BLOCK( p, RZ );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -104,16 +142,14 @@ int main(void)
|
||||
|
||||
make_leak();
|
||||
x = array[0]; // use after free (ok without MALLOCLIKE/MAKE_MEM_NOACCESS)
|
||||
// (nb: initialised because is_zeroed==1 above)
|
||||
// unfortunately not identified as being in a free'd
|
||||
// block because the freeing of the block and shadow
|
||||
// chunk isn't postponed.
|
||||
|
||||
// Bug 137073: passing 0 to MALLOCLIKE_BLOCK was causing an assertion
|
||||
// failure. Test for this (and likewise for FREELIKE_BLOCK).
|
||||
VALGRIND_MALLOCLIKE_BLOCK(0,0,0,0);
|
||||
VALGRIND_FREELIKE_BLOCK(0,0);
|
||||
|
||||
|
||||
checkredzone();
|
||||
|
||||
return x;
|
||||
|
||||
// leak from make_leak()
|
||||
|
||||
@ -1,45 +1,108 @@
|
||||
Invalid write of size 4
|
||||
at 0x........: main (custom_alloc.c:79)
|
||||
at 0x........: main (custom_alloc.c:117)
|
||||
Address 0x........ is 0 bytes after a block of size 40 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Invalid write of size 4
|
||||
at 0x........: main (custom_alloc.c:83)
|
||||
at 0x........: main (custom_alloc.c:121)
|
||||
Address 0x........ is 0 bytes after a block of size 20 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: main (custom_alloc.c:90)
|
||||
at 0x........: main (custom_alloc.c:128)
|
||||
|
||||
Invalid write of size 4
|
||||
at 0x........: main (custom_alloc.c:93)
|
||||
at 0x........: main (custom_alloc.c:131)
|
||||
Address 0x........ is 0 bytes after a block of size 28 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Invalid free() / delete / delete[] / realloc()
|
||||
at 0x........: main (custom_alloc.c:96)
|
||||
at 0x........: main (custom_alloc.c:134)
|
||||
Address 0x........ is 4 bytes inside a block of size 28 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Invalid free() / delete / delete[] / realloc()
|
||||
at 0x........: custom_free (custom_alloc.c:54)
|
||||
by 0x........: main (custom_alloc.c:100)
|
||||
by 0x........: main (custom_alloc.c:138)
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
|
||||
Mismatched free() / delete / delete []
|
||||
at 0x........: custom_free (custom_alloc.c:54)
|
||||
by 0x........: main (custom_alloc.c:103)
|
||||
by 0x........: main (custom_alloc.c:141)
|
||||
Address 0x........ is 0 bytes inside a block of size 40 alloc'd
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (custom_alloc.c:102)
|
||||
by 0x........: main (custom_alloc.c:140)
|
||||
|
||||
Invalid read of size 4
|
||||
at 0x........: main (custom_alloc.c:106)
|
||||
at 0x........: main (custom_alloc.c:144)
|
||||
Address 0x........ is 0 bytes inside a block of size 28 free'd
|
||||
at 0x........: custom_free (custom_alloc.c:54)
|
||||
by 0x........: main (custom_alloc.c:98)
|
||||
by 0x........: main (custom_alloc.c:136)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:68)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 1 bytes before a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:69)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 8 bytes before a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:73)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 0 bytes after a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:74)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 7 bytes after a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:83)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 1 bytes before a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:84)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 8 bytes before a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:88)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 0 bytes after a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:89)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 7 bytes after a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:90)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 8 bytes after a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
|
||||
@ -1,45 +1,108 @@
|
||||
Invalid write of size 4
|
||||
at 0x........: main (custom_alloc.c:79)
|
||||
at 0x........: main (custom_alloc.c:117)
|
||||
Address 0x........ is 0 bytes after a block of size 40 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Invalid write of size 4
|
||||
at 0x........: main (custom_alloc.c:83)
|
||||
at 0x........: main (custom_alloc.c:121)
|
||||
Address 0x........ is 0 bytes after a block of size 20 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: main (custom_alloc.c:90)
|
||||
at 0x........: main (custom_alloc.c:128)
|
||||
|
||||
Invalid write of size 4
|
||||
at 0x........: main (custom_alloc.c:93)
|
||||
at 0x........: main (custom_alloc.c:131)
|
||||
Address 0x........ is 0 bytes after a block of size 28 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Invalid free() / delete / delete[] / realloc()
|
||||
at 0x........: main (custom_alloc.c:96)
|
||||
at 0x........: main (custom_alloc.c:134)
|
||||
Address 0x........ is 4 bytes inside a block of size 28 alloc'd
|
||||
at 0x........: custom_alloc (custom_alloc.c:47)
|
||||
by 0x........: main (custom_alloc.c:76)
|
||||
by 0x........: main (custom_alloc.c:114)
|
||||
|
||||
Invalid free() / delete / delete[] / realloc()
|
||||
at 0x........: custom_free (custom_alloc.c:54)
|
||||
by 0x........: main (custom_alloc.c:100)
|
||||
by 0x........: main (custom_alloc.c:138)
|
||||
Address 0x........ is not stack'd, malloc'd or (recently) free'd
|
||||
|
||||
Mismatched free() / delete / delete []
|
||||
at 0x........: custom_free (custom_alloc.c:54)
|
||||
by 0x........: main (custom_alloc.c:103)
|
||||
by 0x........: main (custom_alloc.c:141)
|
||||
Address 0x........ is 0 bytes inside a block of size 40 alloc'd
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (custom_alloc.c:102)
|
||||
by 0x........: main (custom_alloc.c:140)
|
||||
|
||||
Invalid read of size 1
|
||||
at 0x........: main (custom_alloc.c:106)
|
||||
at 0x........: main (custom_alloc.c:144)
|
||||
Address 0x........ is 0 bytes inside a block of size 28 free'd
|
||||
at 0x........: custom_free (custom_alloc.c:54)
|
||||
by 0x........: main (custom_alloc.c:98)
|
||||
by 0x........: main (custom_alloc.c:136)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:68)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 1 bytes before a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:69)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 8 bytes before a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:73)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 0 bytes after a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:74)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 7 bytes after a block of size 20 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:66)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:83)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 1 bytes before a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:84)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 8 bytes before a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:88)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 0 bytes after a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:89)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 7 bytes after a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
Invalid write of size 1
|
||||
at 0x........: checkredzone (custom_alloc.c:90)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
Address 0x........ is 8 bytes after a recently re-allocated block of size 10 alloc'd
|
||||
at 0x........: checkredzone (custom_alloc.c:81)
|
||||
by 0x........: main (custom_alloc.c:151)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user