This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Buffer Overflow Attacks


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]