Vulnerability Development mailing list archives

safe mallocs (was Re: vulndev-1 and a suggestion about the ensuing discussion)


From: Bennett Todd <bet () rahul net>
Date: Thu, 15 May 2003 21:49:31 -0400

2003-05-15T12:46:57 xenophi1e:
On a related note, how many ways are there of preventing this sort of 
error, or at least preventing it from being a security issue?
[...]
2) Use canaries in the allocator. What's the best way to do this? For one 
byte overflows a simple value at the end that's difficult to guess would 
have saved this snippet from being 0wn3d. What about a longer overflow as 
might have resulted from using strcpy?

For immediate detection you need something cleverer; in the worst
case, you've gotta enlist the aid of the vm subsystem.

But sufficient for this case, and possibly enough to be of some
general use, is a strategy I used in an emalloc() wrapper I wrote
back in the '80s, part of libbent, dunno if that's still around
anywhere, I don't have a copy anymore. It started by my just making
a library of things I did so often I could type 'em without having
to think, the first was probably

        FILE *efopen(char *name, char *mode) {
                FILE *ret;
                if (ret = fopen(name, mode)) {
                        return ret;
                }
                (void) fprintf(stderr, "%s: %s: %s\n", progname, name, strerr(errno));
                exit(1);
        }

(that may be slightly off, it's been maybe 15 years since I've typed
it:-).

When I got around to wrapping malloc, I decided to get a smigeon
cleverer. I wrapped so emalloc returned a char *, just like malloc,
but the char* it returned was the result of mallocing the original
size(rounded up to pessimal alignment) + 2*sizeof(somestruct), where
somestruct was constructed to be pessimally aligned, and had a
canary, as well as a length field. The original malloc request
length got stuffed into the length field in the struct at the
beginning and end, and both structs had their canary fields
initialized as well.

erealloc and efree checked to make sure the ptrs they were handed
had prepended valid canary struct, used the length in it to find and
check the trailing one, then freed the "real" malloc pointer to the
beginning of the prepended malloc struct.

I can't recall it ever actually helping me by catching a bug, but it
pleased me at the time.

-Bennett

Attachment: _bin
Description:


Current thread: