Bugtraq mailing list archives

Re: Smashing the stack


From: Thomas.Pornin () ens fr (Thomas Pornin)
Date: Wed, 22 Jan 1997 10:12:06 +0100


Terrell Thacker writes:
X86 memory protection is based on two segments types: Code and Data.
Code segments are executable with a read toggle.  Data segments
are not executable with a write toggle.  You cannot write to memory
using a code segment selector.  You cannot read memory using a code
segment selector that is not readable.  You cannot execute code using
a data segment selector.  The only selectors allowed in the stack
segment register are ones that are type Data/read/write.  The only
selectors allowed in the code segment register are type Code.  The
only selectors allowed in the general purpose data registers are
type Data or Code/read.

The problem lies with implementations on the X86.  Different types
of selectors can be created to access the same memory in different
ways.  If you want a flat address space for each process, then there
will be the two types of selectors accessing the same memory space,
code and data. Now the code segment selector can be used to execute
the data modified in the stack or data segment.  Does anyone know of
implementations that use different areas of memory for the selectors
of each process?

Actually, you can declare a segment as a data one, with read and write
enable, and load it into the code segment register; this way, you may
have a writable and executable segment. This is not a widely used feature,
as it is much more elegant to use a data segment covering the same range
than the code segment considered.

Nevertheless, using these segments is a pain; that's why linux relies
on paging to perform memory protection and forgets the segments (all
segment registers are declared as 4 GB ones, beginning at adress 0).
I suspect all other 386-based Unixes act this way, as it simplifies much
the implementation. Pages (which are 4 KB wide) can be marked as
readable and writable; no executable flag.

Paging does not exist on 286; therefore, any Unix running on a 286
(but not on a 8086) is likely to use separate code segments and data
segments, and so being unable to execute code placed in data or stack
segments.

        --Thomas Pornin



Current thread: