George <greerga@CIRCLEMUD.ORG> writes: > If you look inside the glibc2 malloc library, there are functions called > 'malloc_check,' 'free_check,' etc which would help in the case of > corrupting the malloc structures. Unfortunately, they don't exist in > glibc2 by default. You have to recompile the malloc library and link it > with your program. You may be able to use the malloc 'hooks' feature but I > haven't tried that. For now I've decided to handle it through a pair of guard functions and ignore arbitrary free()ing. It adds 2*getpagesize() to every malloc, so it's not very efficient and shouldn't be used for anything frequently allocated. Right now I'm using it for buf, buf1, buf2, and arg. It has proven quite effective (in test cases... my mud currently doesn't have any overruns because I'm using rather large buffers at the moment). It works well on linux, and I expect it would work on any posix compliant system (though getpagesize() is a BSD and svr4 command according to man.. I believe there are appropriate constants defined in the standard header limits.h.). On a buffer overrun or underrun (that is smaller than 4k... which I imagine is just about all of them), a segment violation will be generated. My next step will be to add semi-automatic stack protection (via a pair of macros). Something like #define STACK_GUARD() char stack_guard[4096]; \ mprotect(stack_guard, 4096, PROT_READ) #define STACK_UNGUARD() \ mprotect(stack_guard, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) #define STACK_RETURN(n) \ mprotect(stack_guard, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);\ return (n) Then it would be called like int myfunc() { int x; char buf[256]; STACK_GUARD(); /* stuff happens */ if (blah < 0) STACK_RETURN(-1); else /* more stuff */ /* yet more stuff */ STACK_UNGUARD(); } Below are the guarded malloc/free functions. void * mud_malloc_guarded(size_t nbytes) { void *p; int pagesize; assert((nbytes > 0) && (nbytes < 5*1024*1024)); pagesize = getpagesize(); nbytes = ((nbytes / pagesize) + 1) * pagesize; p = valloc(nbytes + 2 * pagesize); if (!p) { sprintf(errbuf, "mud_malloc_guarded failure for %d bytes", nbytes); perror(errbuf); abort(); } bzero(p, nbytes + 2 * pagesize); if (mprotect(p, pagesize, PROT_READ) < 0) slog("SYSERR: mprotect, %s", strerror(errno)); if (mprotect((char *)p + pagesize + nbytes, pagesize, PROT_READ) < 0) slog("SYSERR: mprotect, %s", strerror(errno)); num_allocs++; bytes_alloc+=nbytes; return (void *)(((char *)p)+pagesize); } void mud_free_guarded(void *ptr) { num_frees++; free((char *)ptr - getpagesize()); return; } -- James Turner turnerjh@xtn.net http://www.vuse.vanderbilt.edu/~turnerjh/ +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/15/00 PST