Vulnerability Development mailing list archives

Re: Getting passwords from the heap?


From: Jason Spence <thalakan () lightconsulting com>
Date: Wed, 27 Jun 2001 12:01:35 -0700

On Wed, Jun 27, 2001 at 05:22:31PM +0100, Aigars Grins developed
a new theory of relativity and: 

Sorry for my bad english.. The following applies for OpenBSD 2.7 (and most
likely later versions as well). A more OpenBSD savvy programmer can propably
correct me on a lot of details (please do).

Malloc() uses sbrk() to access memory from the OS. This gives malloc() a
'static' area to work with. Static in the sense that it's always a single
continuous space (the end point is what changes when it gets/gives resources
from/to the OS). This space is continous from userland perspective, ie. the
space is not a continous physical RAM space.

This is true.  What confuses me is that when I do a grep on the entire
source tree, I find this:

==============================================================================
/*
 * unimplemented VM system calls:
 */

/*
 * sys_sbrk: sbrk system call.
 */

/* ARGSUSED */
int
sys_sbrk(p, v, retval)
        struct proc *p;
        void *v;
        register_t *retval;
{
#if 0
        struct sys_sbrk_args /* {
                syscallarg(intptr_t) incr;
        } */ *uap = v;
#endif

        return (ENOSYS);
}
==============================================================================

Then I looked at the man page and found this:

DESCRIPTION 
     The brk() and sbrk() functions are historical curiosities left
     over from earlier days before the advent of virtual memory
     management.

I looked at the malloc source and found that it still is, in fact,
calling sbrk() somewhere.  I found some stuff in
src/lib/libc/arch/x/sbrk.S, but it seems to be just a syscall gate
wrapper for SYS_break, which I'm having trouble finding.

Calloc() simply calls malloc() and then zeros out the space. Malloc does no
zero'ing at all (hence it's more efficient).

I looked at the source and found that you can do three things to
change the behavior of malloc:

 - Symlink /etc/malloc.conf to a fictitious name consisting of a
   string of characters defined in the man page

 - Define an environment variable named MALLOC_OPTIONS

 - Define a global variable in your program named malloc_optioins

All of these allow you to set the J or Z flags, which will fill your
allocated memory with 0xd0 or 0x00, respectively.  It looks like it
sets the J flag implicitly when you set the Z flag, but will still
zero the memory it gives you and put the junk byte into memory that
malloc allocates internally.  A quick check shows that FreeBSD
4.2-CURRENT supports the same mechanism.  If you do not use the J or Z
flags, your memory IS NOT ZEROED.  I ran my program on an OpenBSD 2.8
box and confirmed this.

glibc (from Linux land) has a similar mechanism using the environment
variable MALLOC_CHECK, but it doesn't seem that it offers a mechanism
to zero the pages (although it seems that you could maybe hook mtrace,
but that's pure speculation).

On a side note, a quick check makes it seem that none of them use the
x86 vector instructions (MMX, 3dNOW!, KNI, etc) to do memset() on the
memory, which would probably be a decent speed win for the time it
would take to construct the assembly primitives and write the kernel
config glue to enable them based on the processor type.  The Linux
kernel uses them for moving memory, but it doesn't seem that the C
libraries take advantage of them.

None of this applies to statically allocated variables; I need to
research how the compiler does these things to answer that question.
I'm going to email the gcc devel list and see what they have to say
about it; the gcc source is opaque to me :)

What would be really really nice would be an option using those
mechanisms to zero the memory upon calling free().  It seems to be
near-trivial to do in OpenBSD: see ifree(), free_page() and
free_bytes() in src/lib/libc/stdlib/malloc.c.  Just add a memset call
and a variable initialized in malloc_init() using the malloc.conf
mechanism and you're all set :)  If there are any OpenBSD people on
this list, I'd like to talk to you about the social issues regarding
submitting patches to the OpenBSD core team; I want to do this.

Of course, that doesn't help us with compiler-allocated memory for
static vars allocated on the stack, but it's a start.

A programmer should of course never count on anything wiping anything except
if he/she says so explicitly.

That pretty much sums up what I've discovered so far.

-- 
 - Jason

What is the difference between a Turing machine and the modern computer?
It's the same as that between Hillary's ascent of Everest and the
establishment of a Hilton on its peak.


Current thread: