[U-Boot] bug in malloc/calloc and setting of MORECORE_CLEARS
Kumar Gala
galak at kernel.crashing.org
Mon Nov 15 20:45:46 CET 2010
On Nov 13, 2010, at 10:34 AM, Kumar Gala wrote:
> I've been debugging a "memory corruption" issue and it seems to come down to how we set MORECORE_CLEARS
>
> from malloc.h:
>
> MORECORE (default: sbrk)
> The name of the routine to call to obtain more memory from the system.
> MORECORE_FAILURE (default: -1)
> The value returned upon failure of MORECORE.
> MORECORE_CLEARS (default 1)
> True (1) if the routine mapped to MORECORE zeroes out memory (which
> holds for sbrk).
>
>
> So the issue I'm seeing is that we zero out memory in mem_malloc_init(). Thus our sbrk implementation just does simple record keeping. However we can get into the following situation:
>
> a1 = malloc(LARGE_SZ); /* causes internals to call sbrk */
> ...
> /* use memory at 'a1' */
> ...
> free(a1); /* causes internals to call malloc_trim, malloc_trim decides to return memory to sbrk, memory is now nonzero */
>
> a2 = calloc(SIZE); /* internals assume sbrk memory is zero because of MORECORE_CLEARS setting, however its not */
>
> ... BAD THINGS HAPPEN ...
>
>
> I'm guessing we haven't seen much of this because there aren't that many users of calloc today. I happen to see it related to NAND code which has kzalloc defined as calloc.
Here's an example test case that fails if execute right after:
mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);
{
void *p1;
u8 *p2;
int i;
printf("MALLOC TEST\n");
p1 = malloc(135176);
printf("P1 = %p\n", p1);
memset(p1, 0xab, 135176);
free(p1);
p2 = calloc(4097, 1);
printf("P2 = %p %p\n", p2, p2 + 4097);
for (i = 0; i < 4097; i++) {
if (p2[i] != 0)
printf("miscompare at byte %d got %x\n", i, p2[i]);
}
free(p2);
printf("END MALLOC TEST\n\n");
}
More information about the U-Boot
mailing list