Hello Theo, Apparently the new malloc(3) implementation doesn't stop me from writing past the end of buffer as long as I am inside the last page. (Please forgive me beforehand if I am missing something too obvious) consider the following program: ---- // We just want to see how far after end of allocated buffer we can go. // Allocate a buffer, then try to read past it, see how far we can go before // System notices. // myhandler should tell us about this. If you don't trust it just disable and // examine the core file created. // #include <stdio.h> #include <sys/types.h> #include <sys/mman.h> #include <signal.h>
#define PAGE_SIZE 4096 char *s; int i; int size; void myhandler(int sig) { printf("Caught Signal %d\n", sig); printf("s=0x%x, size=%d, i=%d\n", s, size, i); perror("last err condition"); exit(0); } main(int ac, char *av[]) { if (ac != 2) { printf("%s <size>\n", av[0]); exit(1); } size = atoi(av[1]); if (size < 4096) { printf ("size should be larger than 4K.\n"); exit(1); } signal(SIGSEGV, myhandler); s = (char *)malloc(size); for (i = 0; i < 2 * size - 1; i++) s[i] = (char )i; free(s); } ---- and here is the execution (a very recent install as you can see): ---- #dmesg | head -6 OpenBSD 3.8-beta (GENERIC.MP) #277: Mon Aug 22 23:04:26 MDT 2005 [EMAIL PROTECTED]:/usr/src/sys/arch/i386/compile/GENERIC.MP cpu0: Intel Pentium III ("GenuineIntel" 686-class) 869 MHz cpu0: FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,ME real mem = 804823040 (785960K) avail mem = 727044096 (710004K) # gcc malloc-test.c # ./a.out 4096 Caught Signal 11 s=0x8a19d000, size=4096, i=4096 last err condition: Undefined error: 0 # ./a.out 4097 Caught Signal 11 s=0x7f0eb000, size=4097, i=8192 last err condition: Undefined error: 0 # Is this the way it is supposed to be? cheers, Masoud Sharbiani On Mon, Aug 22, 2005 at 05:33:40PM -0600, Theo de Raadt wrote: > We are heading towards making the real 3.8 release soonish. I would > like to ask the community to do lots of testing over the next week if > they can. > > This release will bring a lot of new ideas from us. One of them in > particular is somewhat risky. I think it is time to talk about that > one, and let people know what is ahead on our road. > > Traditionally, Unix malloc(3) has always just "extended the brk", > which means extending the traditional Unix process data segment to > allocate more memory. malloc(3) would simply extend the data segment, > and then calve off little pieces to requesting callers as needed. It > also remembered which pieces were which, so that free(3) could do it's > job. > > The way this was always done in Unix has had a number of consequences, > some of which we wanted to get rid of. In particular, malloc & free > have not been able to provide strong protection against overflows or > other corruption. > > Our malloc implementation is a lot more resistant (than Linux) to > "heap overflows in the malloc arena", but we wanted to improve things > even more. > > Starting a few months ago, the following changes were made: > > - We made the mmap(2) system call return random memory addresses. As well > the kernel ensures that two objects are not mapped next to each other; > in effect, this creates unallocated memory which we call a "guard page". > > - We have changed malloc(3) to use mmap(2) instead of extending the data > segment via brk() > > - We also changed free(3) to return memory to the kernel, un-allocating > them out of the process. > > - As before, objects smaller than a page are allocated within shared > pages that malloc(3) maintains. But their allocation is now somewhat > randomized as well. > > - A number of other similar changes which are too dangerous for normal > software or cause too much of a slowdown are available as malloc options > as described in the manual page. These are very powerful for debugging > buggy applications. > > Other results: > > - When you free an object that is >= 1 page in size, it is actually > returned to the system. Attempting to read or write to it after > you free is no longer acceptable. That memory is unmapped. You get > a SIGSEGV. > > - For a decade and a bit, we have been fixing software for buffer overflows. > Now we are finding a lot of software that reads before the start of the > buffer, or reads too far off the end of the buffer. You get a SIGSEGV. > > To some of you, this will sound like what the Electric Fence toolkit > used to be for. But these features are enabled by default. Electric > Fence was also very slow. It took nearly 3 years to write these > OpenBSD changes since performance was a serious consideration. (Early > versions caused a nearly 50% slowdown). > > Our changes have tremendous benefits, but until some bugs in external > packages are found and fixed, there are some risks as well. Some > software making incorrect assumptions will be running into these new > security technologies. > > I discussed this in talks I have given before: I said that we were > afraid to go ahead with guard pages, because a lot of software is just > written to such low standards. Applications over-read memory all the > time, go 1 byte too far, read 1 byte too early, access memory after free, > etc etc etc. > > Oh well -- we've decided that we will try to ship with this protection > mechanism in any case, and try to solve the problems as we run into > them. > > Two examples: > > Over the last two months, some OpenBSD users noticed that the X server > was crashing occasionally. Two bugs have been diagnosed and fixed by > us. One was a use-after-free bug in the X shared library linker. The > other was a buffer-over-read bug deep down in the very lowest level > fb* pixmap compositing routines. The latter bug in particular was > very difficult to diagnose and fix, and is about 10 years old. We > have found other bugs like this in other external software, and even a > few in the base OpenBSD tree (though those were found a while back, > even as we started experimenting with the new malloc code). > > I would bet money that the X fb* bug has crashed Linux (and other) X > servers before. It is just that it was very rare, and noone ever > chased it. The new malloc we have just makes code get lucky less > often, which lets us get to the source of a bug easier. As a > programmer, I appreciate anything which makes bugs easier to > reproduce. > > We expect that our malloc will find more bugs in software, and this > might hurt our user community in the short term. We know that what > this new malloc is doing is perfectly legal, but that realistically > some open source software is of such low quality that it is just not > ready for these things to happen. > > We ask our users to help us uncover and fix more of these bugs in > applications. Some will even be exploitable. Instead of saying that > OpenBSD is busted in this regard, please realize that the software > which is crashing is showing how shoddily it was written. Then help > us fix it. For everyone.. not just OpenBSD users.