Commit Graph

6 Commits

Author SHA1 Message Date
Kirill Smelkov
646b51833f lib/bcheck: Prevent libc_malloc/libc_free etc from being miscompiled
On i386 and gcc-4.7 I found that libc_malloc was miscompiled - look:

static void *libc_malloc(size_t size)
{
    void *ptr;
    restore_malloc_hooks();     // __malloc_hook = saved_malloc_hook
    ptr = malloc(size);
    install_malloc_hooks();     // saved_malloc_hook = __malloc_hook, __malloc_hook = __bound_malloc
    return ptr;
}

	.type	libc_malloc, @function
libc_malloc:
.LFB56:
	.cfi_startproc
	pushl	%edx
	.cfi_def_cfa_offset 8
	movl	%eax, (%esp)
	call	malloc
	movl	$__bound_malloc, __malloc_hook
	movl	$__bound_free, __free_hook
	movl	$__bound_realloc, __realloc_hook
	movl	$__bound_memalign, __memalign_hook
	popl	%ecx
	.cfi_def_cfa_offset 4
	ret

Here gcc inlined both restore_malloc_hooks() and install_malloc_hooks()
and decided that

    saved_malloc_hook -> __malloc_hook -> saved_malloc_hook

stores are not needed and could be ommitted. Only it did not know
__molloc_hook affects malloc()...

So add compiler barrier to both install and restore hooks functions and
be done with it - the code is now ok:

    diff --git a/bcheck0.s b/bcheck1.s
    index 5f50293..4c02a5f 100644
    --- a/bcheck0.s
    +++ b/bcheck1.s
    @@ -42,8 +42,24 @@ libc_malloc:
            .cfi_startproc
            pushl   %edx
            .cfi_def_cfa_offset 8
    +       movl    saved_malloc_hook, %edx
    +       movl    %edx, __malloc_hook
    +       movl    saved_free_hook, %edx
    +       movl    %edx, __free_hook
    +       movl    saved_realloc_hook, %edx
    +       movl    %edx, __realloc_hook
    +       movl    saved_memalign_hook, %edx
    +       movl    %edx, __memalign_hook
            movl    %eax, (%esp)
            call    malloc
    +       movl    __malloc_hook, %edx
    +       movl    %edx, saved_malloc_hook
    +       movl    __free_hook, %edx
    +       movl    %edx, saved_free_hook
    +       movl    __realloc_hook, %edx
    +       movl    %edx, saved_realloc_hook
    +       movl    __memalign_hook, %edx
    +       movl    %edx, saved_memalign_hook
            movl    $__bound_malloc, __malloc_hook
            movl    $__bound_free, __free_hook
            movl    $__bound_realloc, __realloc_hook

For barrier I use

    __asm__ __volatile__ ("": : : "memory")

which is used as compiler barrier by Linux kernel, and mentioned in gcc
docs and in wikipedia [1].

Without this patch any program compiled with tcc -b crashes in startup
because of infinite recursion in libc_malloc.

[1] http://en.wikipedia.org/wiki/Memory_ordering#Compiler_memory_barrier
2012-11-13 22:17:51 +04:00
Michael Matz
b068e29df7 x86_64: Implement GET_CALLER_FP
TCC always uses %rbp frames, so we can use that one.
2012-04-18 20:57:13 +02:00
Thomas Preud'homme
776364f395 Add support for __FreeBSD_kernel__ kernel
Add support for kfreebsd-i386 and kfreebsd-amd64 Debian arch with
thanks to Pierre Chifflier <chifflier@cpe.fr>.
2010-09-10 21:09:07 +02:00
grischka
7fa712e00c win32: enable bounds checker & exception handler
exception handler borrowed from k1w1. Thanks.
2009-12-19 22:22:43 +01:00
grischka
0085c648f6 bcheck: restore malloc hooks when done 2009-07-18 21:54:47 +02:00
grischka
ea5e81bd6a new subdirs: include, lib, tests 2009-04-18 15:08:03 +02:00