From mboxrd@z Thu Jan 1 00:00:00 1970 From: Florian Weimer To: Frank Pilhofer Cc: gcc@gcc.gnu.org Subject: Re: Buffer Overflow Attacks Date: Sun, 14 Oct 2001 10:50:00 -0000 Message-id: <873d4m1473.fsf@deneb.enyo.de> References: <20011014140920.A657@rose.fpx.de> X-SW-Source: 2001-10/msg00816.html 520065607613-0001@t-online.de (Frank Pilhofer) writes: > If my limited comprehension of this topic is correct, buffer over- > flow exploits are based on the fact that you can overwrite vital parts > like processor registers and a function's return address, which are > stored on the stack just as local variables are. Nowadays, Buffer overflow exploits sometimes involve overwriting function pointers on the heap. Since buffers and function pointers are sometimes part of the same data structure, it is difficult to separate them in the address space. Sometimes, buffer overflow bugs are not just related to buffer overflows, but they give you complete control what you can write *anywhere* (one of the recent fetchmail problems was of this type). > This idea would not work if it is not possible to have two stack seg- > ments. You could place the two parts into different address ranges of > the stack segment, though. If the registers/addresses parts is on a > smaller virtual address, your program would likely run out of real > memory whilst the attacker sends data before the wrap-around occurs > (or fail upon hitting a read-only address). You could unmap a page between these to memory areas. > So basically, I am wondering if the compiler could do something to > blunt buffer overflow attacks. I know, that is not the prime purpose > of the compiler but rather the responsibility of the programmer, but > still I find it an attractive idea as a one-step fix for all such > exploits. There isn't one. Suppose you have an object of this type ("func_ptr_t" is some function pointer): struct s { char buffer[32]; func_ptr_t ptr; }; Then a statement like s.buffer[32] = 1; is completely legal. It is equivalent to: *((s.buffer) + 32) = 1; "(s.buffer) + 32" is a valid pointer to a character because every object can be read and written as sequence of characters. From the point of view of the C language, no buffer overflow occurs, but this clearly unsatisfactory from a safety point of view because quite a few buffer overflow bugs are of this type.